liushengqiang 1 рік тому
коміт
40d831f802
100 змінених файлів з 10978 додано та 0 видалено
  1. 24 0
      .gitignore
  2. 18 0
      README.md
  3. 9 0
      auto-imports.d.ts
  4. 63 0
      components.d.ts
  5. 40 0
      image2code.js
  6. 22 0
      index.html
  7. 59 0
      package.json
  8. 4012 0
      pnpm-lock.yaml
  9. 107 0
      public/abc2svg/abc2svg-1.js
  10. 366 0
      public/abc2svg/abcweb-1.js
  11. 1 0
      public/abc2svg/jquery-1.11.1.min.js
  12. 820 0
      public/abc2svg/snd-1.js
  13. 1984 0
      public/abc2svg/xml2abc.js
  14. BIN
      public/favicon.ico
  15. 55 0
      public/flexible.js
  16. 11 0
      public/loading.svg
  17. BIN
      public/soundFonts/flute-mp3/A4.mp3
  18. BIN
      public/soundFonts/flute-mp3/A5.mp3
  19. BIN
      public/soundFonts/flute-mp3/A6.mp3
  20. BIN
      public/soundFonts/flute-mp3/Ab4.mp3
  21. BIN
      public/soundFonts/flute-mp3/Ab5.mp3
  22. BIN
      public/soundFonts/flute-mp3/Ab6.mp3
  23. BIN
      public/soundFonts/flute-mp3/B4.mp3
  24. BIN
      public/soundFonts/flute-mp3/B5.mp3
  25. BIN
      public/soundFonts/flute-mp3/B6.mp3
  26. BIN
      public/soundFonts/flute-mp3/Bb4.mp3
  27. BIN
      public/soundFonts/flute-mp3/Bb5.mp3
  28. BIN
      public/soundFonts/flute-mp3/Bb6.mp3
  29. BIN
      public/soundFonts/flute-mp3/C4.mp3
  30. BIN
      public/soundFonts/flute-mp3/C5.mp3
  31. BIN
      public/soundFonts/flute-mp3/C6.mp3
  32. BIN
      public/soundFonts/flute-mp3/C7.mp3
  33. BIN
      public/soundFonts/flute-mp3/D4.mp3
  34. BIN
      public/soundFonts/flute-mp3/D5.mp3
  35. BIN
      public/soundFonts/flute-mp3/D6.mp3
  36. BIN
      public/soundFonts/flute-mp3/Db4.mp3
  37. BIN
      public/soundFonts/flute-mp3/Db5.mp3
  38. BIN
      public/soundFonts/flute-mp3/Db6.mp3
  39. BIN
      public/soundFonts/flute-mp3/E4.mp3
  40. BIN
      public/soundFonts/flute-mp3/E5.mp3
  41. BIN
      public/soundFonts/flute-mp3/E6.mp3
  42. BIN
      public/soundFonts/flute-mp3/Eb4.mp3
  43. BIN
      public/soundFonts/flute-mp3/Eb5.mp3
  44. BIN
      public/soundFonts/flute-mp3/Eb6.mp3
  45. BIN
      public/soundFonts/flute-mp3/F4.mp3
  46. BIN
      public/soundFonts/flute-mp3/F5.mp3
  47. BIN
      public/soundFonts/flute-mp3/F6.mp3
  48. BIN
      public/soundFonts/flute-mp3/G4.mp3
  49. BIN
      public/soundFonts/flute-mp3/G5.mp3
  50. BIN
      public/soundFonts/flute-mp3/G6.mp3
  51. BIN
      public/soundFonts/flute-mp3/Gb4.mp3
  52. BIN
      public/soundFonts/flute-mp3/Gb5.mp3
  53. BIN
      public/soundFonts/flute-mp3/Gb6.mp3
  54. 0 0
      src/assets/iconfont.js
  55. 1 0
      src/assets/vue.svg
  56. 24 0
      src/components/The-error/index.tsx
  57. 7 0
      src/components/The-icon/index.css
  58. 36 0
      src/components/The-icon/index.tsx
  59. 0 0
      src/components/the-audio/index.module.less
  60. 20 0
      src/components/the-audio/index.tsx
  61. 19 0
      src/components/the-video/index.module.less
  62. 32 0
      src/components/the-video/index.tsx
  63. 0 0
      src/constant/audios.ts
  64. 218 0
      src/constant/instruments.ts
  65. 215 0
      src/constant/instrumentsClassfiy.ts
  66. 1 0
      src/constant/tockAndTick.json
  67. 27 0
      src/constant/whiteUrl.ts
  68. 7 0
      src/env.d.ts
  69. 267 0
      src/helpers/calcSpeed.ts
  70. 219 0
      src/helpers/communication.ts
  71. 12 0
      src/helpers/eventemitter.ts
  72. 1025 0
      src/helpers/formateMusic.ts
  73. 439 0
      src/helpers/metronome.ts
  74. 23 0
      src/helpers/parseABC.ts
  75. 78 0
      src/pc/App.tsx
  76. 70 0
      src/pc/api.ts
  77. 140 0
      src/pc/component/keys/index.module.less
  78. 118 0
      src/pc/component/keys/index.tsx
  79. 6 0
      src/pc/component/notes/index.module.less
  80. 78 0
      src/pc/component/notes/index.tsx
  81. 49 0
      src/pc/home/component/file-btn/index.module.less
  82. 104 0
      src/pc/home/component/file-btn/index.tsx
  83. 26 0
      src/pc/home/component/the-btn/index.module.less
  84. 39 0
      src/pc/home/component/the-btn/index.tsx
  85. 0 0
      src/pc/home/component/the-setting/index.module.less
  86. 30 0
      src/pc/home/component/the-setting/index.tsx
  87. 8 0
      src/pc/home/component/the-speed/index.module.less
  88. 49 0
      src/pc/home/component/the-speed/index.tsx
  89. BIN
      src/pc/home/images/icon_0.png
  90. BIN
      src/pc/home/images/icon_1.png
  91. BIN
      src/pc/home/images/icon_10.png
  92. BIN
      src/pc/home/images/icon_11.png
  93. BIN
      src/pc/home/images/icon_12.png
  94. BIN
      src/pc/home/images/icon_13.png
  95. BIN
      src/pc/home/images/icon_14.png
  96. BIN
      src/pc/home/images/icon_15.png
  97. BIN
      src/pc/home/images/icon_16.png
  98. BIN
      src/pc/home/images/icon_17.png
  99. BIN
      src/pc/home/images/icon_18.png
  100. BIN
      src/pc/home/images/icon_19.png

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+osmd-extended
+node_modules
+# dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 18 - 0
README.md

@@ -0,0 +1,18 @@
+# Vue 3 + TypeScript + Vite
+
+This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support For `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+   1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+   2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.

+ 9 - 0
auto-imports.d.ts

@@ -0,0 +1,9 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// noinspection JSUnusedGlobalSymbols
+// Generated by unplugin-auto-import
+export {}
+declare global {
+
+}

+ 63 - 0
components.d.ts

@@ -0,0 +1,63 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// Generated by unplugin-vue-components
+// Read more: https://github.com/vuejs/core/pull/3399
+import '@vue/runtime-core'
+
+export {}
+declare module "@vue/runtime-core" {
+	export interface GlobalComponents {
+		RouterLink: typeof import("vue-router")["RouterLink"];
+		RouterView: typeof import("vue-router")["RouterView"];
+		NAlert: typeof import("naive-ui")["NAlert"];
+		NAvatar: typeof import("naive-ui")["NAvatar"];
+		NBackTop: typeof import("naive-ui")["NBackTop"];
+		NBadge: typeof import("naive-ui")["NBadge"];
+		NBreadcrumb: typeof import("naive-ui")["NBreadcrumb"];
+		NBreadcrumbItem: typeof import("naive-ui")["NBreadcrumbItem"];
+		NButton: typeof import("naive-ui")["NButton"];
+		NCard: typeof import("naive-ui")["NCard"];
+		NCheckbox: typeof import("naive-ui")["NCheckbox"];
+		NCol: typeof import("naive-ui")["NCol"];
+		NConfigProvider: typeof import("naive-ui")["NConfigProvider"];
+		NCountdown: typeof import("naive-ui")["NCountdown"];
+		NDialogProvider: typeof import("naive-ui")["NDialogProvider"];
+		NDivider: typeof import("naive-ui")["NDivider"];
+		NDrawer: typeof import("naive-ui")["NDrawer"];
+		NDrawerContent: typeof import("naive-ui")["NDrawerContent"];
+		NDropdown: typeof import("naive-ui")["NDropdown"];
+		NForm: typeof import("naive-ui")["NForm"];
+		NFormItem: typeof import("naive-ui")["NFormItem"];
+		NGi: typeof import("naive-ui")["NGi"];
+		NGrid: typeof import("naive-ui")["NGrid"];
+		NGridItem: typeof import("naive-ui")["NGridItem"];
+		NIcon: typeof import("naive-ui")["NIcon"];
+		NInput: typeof import("naive-ui")["NInput"];
+		NInputGroup: typeof import("naive-ui")["NInputGroup"];
+		NLayout: typeof import("naive-ui")["NLayout"];
+		NLayoutContent: typeof import("naive-ui")["NLayoutContent"];
+		NLayoutHeader: typeof import("naive-ui")["NLayoutHeader"];
+		NLayoutSider: typeof import("naive-ui")["NLayoutSider"];
+		NList: typeof import("naive-ui")["NList"];
+		NListItem: typeof import("naive-ui")["NListItem"];
+		NMenu: typeof import("naive-ui")["NMenu"];
+		NMessageProvider: typeof import("naive-ui")["NMessageProvider"];
+		NModal: typeof import("naive-ui")["NModal"];
+		NNotificationProvider: typeof import("naive-ui")["NNotificationProvider"];
+		NProgress: typeof import("naive-ui")["NProgress"];
+		NRadio: typeof import("naive-ui")["NRadio"];
+		NRadioGroup: typeof import("naive-ui")["NRadioGroup"];
+		NRow: typeof import("naive-ui")["NRow"];
+		NSelect: typeof import("naive-ui")["NSelect"];
+		NSkeleton: typeof import("naive-ui")["NSkeleton"];
+		NSpace: typeof import("naive-ui")["NSpace"];
+		NSpin: typeof import("naive-ui")["NSpin"];
+		NSwitch: typeof import("naive-ui")["NSwitch"];
+		NTabPane: typeof import("naive-ui")["NTabPane"];
+		NTabs: typeof import("naive-ui")["NTabs"];
+		NTag: typeof import("naive-ui")["NTag"];
+		NThing: typeof import("naive-ui")["NThing"];
+		NTooltip: typeof import("naive-ui")["NTooltip"];
+	}
+}

+ 40 - 0
image2code.js

@@ -0,0 +1,40 @@
+const fs = require('fs')
+const path = require('path')
+
+// 指法文件夹位置
+// const filesDir = path.join(__dirname, './fingering')
+// const filesDir = path.join(__dirname, './pages/detail')
+const filesDir = path.join(__dirname, './images')
+console.log("🚀 ~ filesDir:", filesDir, path.join(filesDir, 'index.json'))
+
+// 需要处理的文件后缀
+const suffixs = ['png', 'svg']
+
+const files = fs.readdirSync(path.resolve(filesDir))
+// console.log("🚀 ~ files:", files)
+
+;(async function() {
+  let i = 0
+  const exportJson = {}
+  for (const file of files) {
+    const suffix = file.slice(file.lastIndexOf('.') + 1)
+    // console.log("🚀 ~ suffix:", suffix)
+    if (!suffixs.includes(suffix)) continue;
+    const dirFullPath = path.join(filesDir, file)
+    // console.log("🚀 ~ dirFullPath:", dirFullPath)
+    fs.stat(dirFullPath, (err, stat) => {
+      if (!err && !stat.isDirectory()) {
+        const fileNames = file.split('.')
+        const fileBuffer =  fs.readFileSync(dirFullPath)
+        console.log("🚀 ~ fileBuffer:", fileNames[0])
+        const fileType = suffix === 'svg' ? 'svg+xml' : suffix
+        const str = `data:image/${fileType};base64,` + Buffer.from(fileBuffer, 'binary').toString('base64')
+        exportJson[fileNames[0]] = str
+        
+        fs.writeFileSync(path.join(filesDir, 'index.json'), JSON.stringify(exportJson, null, 2))
+      }
+    })
+    // if (i === 0) break;
+  }
+  
+})()

+ 22 - 0
index.html

@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="ZH-cn">
+
+<head>
+  <meta charset="UTF-8">
+  <link rel="icon" href="/favicon.ico" />
+  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
+  <meta http-equiv="Cache-control" content="no-cache">
+  <meta http-equiv="Cache" content="no-cache">
+  <title>打谱</title>
+  <script src="//at.alicdn.com/t/c/font_4186350_idu6dqxtfd.js"></script>
+  <script src="/flexible.js"></script>
+  <script src="/abc2svg/xml2abc.js"></script>
+  <script src="/abc2svg/jquery-1.11.1.min.js"></script>
+</head>
+
+<body>
+  <div id="app"></div>
+  <script type="module" src="/src/pc/main.ts"></script>
+</body>
+
+</html>

+ 59 - 0
package.json

@@ -0,0 +1,59 @@
+{
+  "name": "music-score",
+  "private": true,
+  "version": "0.0.0",
+  "scripts": {
+    "dev": "vite --host --force",
+    "build": "vite build",
+    "preview": "vite preview --open"
+  },
+  "dependencies": {
+    "@arco-design/web-vue": "^2.49.2",
+    "@vant/touch-emulator": "^1.4.0",
+    "@varlet/touch-emulator": "^2.13.4",
+    "@varlet/ui": "^2.13.4",
+    "@vicons/fa": "^0.12.0",
+    "@vicons/ionicons5": "^0.12.0",
+    "abcjs": "^6.2.2",
+    "clean-deep": "^3.4.0",
+    "consola": "^2.15.3",
+    "dayjs": "^1.11.7",
+    "eventemitter3": "^5.0.0",
+    "howler": "^2.2.3",
+    "html2canvas": "^1.4.1",
+    "lodash": "^4.17.21",
+    "naive-ui": "^2.34.4",
+    "plyr": "^3.7.8",
+    "query-string": "^8.1.0",
+    "store": "^2.0.12",
+    "umi-request": "^1.4.0",
+    "vant": "^4.1.2",
+    "vfonts": "^0.0.3",
+    "vue": "^3.2.47",
+    "vue-router": "^4.1.6",
+    "vue3-lottie": "^2.5.0",
+    "ws": "^8.13.0"
+  },
+  "devDependencies": {
+    "@types/howler": "^2.2.7",
+    "@types/lodash": "^4.14.192",
+    "@types/node": "^18.15.11",
+    "@types/store": "^2.0.2",
+    "@vant/use": "^1.5.1",
+    "@vitejs/plugin-legacy": "^4.0.2",
+    "@vitejs/plugin-vue": "^4.1.0",
+    "@vitejs/plugin-vue-jsx": "^3.0.1",
+    "canvg": "^4.0.1",
+    "less": "^4.1.3",
+    "postcss-pxtorem": "^6.0.0",
+    "terser": "^5.16.8",
+    "typescript": "^4.9.3",
+    "unplugin-auto-import": "^0.16.6",
+    "unplugin-vue-components": "^0.24.1",
+    "vite": "^4.2.0",
+    "vite-plugin-mkcert": "^1.15.0",
+    "vite-plugin-style-import": "^2.0.0",
+    "vite-svg-loader": "^4.0.0",
+    "vue-tsc": "^1.2.0"
+  }
+}

+ 4012 - 0
pnpm-lock.yaml

@@ -0,0 +1,4012 @@
+lockfileVersion: '6.0'
+
+dependencies:
+  '@arco-design/web-vue':
+    specifier: ^2.49.2
+    version: 2.49.2(vue@3.2.47)
+  '@vant/touch-emulator':
+    specifier: ^1.4.0
+    version: 1.4.0
+  '@varlet/touch-emulator':
+    specifier: ^2.13.4
+    version: 2.13.4
+  '@varlet/ui':
+    specifier: ^2.13.4
+    version: 2.13.4(vue@3.2.47)
+  '@vicons/fa':
+    specifier: ^0.12.0
+    version: 0.12.0
+  '@vicons/ionicons5':
+    specifier: ^0.12.0
+    version: 0.12.0
+  abcjs:
+    specifier: ^6.2.2
+    version: 6.2.2
+  clean-deep:
+    specifier: ^3.4.0
+    version: 3.4.0
+  consola:
+    specifier: ^2.15.3
+    version: 2.15.3
+  dayjs:
+    specifier: ^1.11.7
+    version: 1.11.7
+  eventemitter3:
+    specifier: ^5.0.0
+    version: 5.0.0
+  howler:
+    specifier: ^2.2.3
+    version: 2.2.3
+  html2canvas:
+    specifier: ^1.4.1
+    version: 1.4.1
+  lodash:
+    specifier: ^4.17.21
+    version: 4.17.21
+  naive-ui:
+    specifier: ^2.34.4
+    version: 2.34.4(vue@3.2.47)
+  plyr:
+    specifier: ^3.7.8
+    version: 3.7.8
+  query-string:
+    specifier: ^8.1.0
+    version: 8.1.0
+  store:
+    specifier: ^2.0.12
+    version: 2.0.12
+  umi-request:
+    specifier: ^1.4.0
+    version: 1.4.0
+  vant:
+    specifier: ^4.1.2
+    version: 4.1.2(vue@3.2.47)
+  vfonts:
+    specifier: ^0.0.3
+    version: 0.0.3
+  vue:
+    specifier: ^3.2.47
+    version: 3.2.47
+  vue-router:
+    specifier: ^4.1.6
+    version: 4.1.6(vue@3.2.47)
+  vue3-lottie:
+    specifier: ^2.5.0
+    version: 2.5.0(vue@3.2.47)
+  ws:
+    specifier: ^8.13.0
+    version: 8.13.0
+
+devDependencies:
+  '@types/howler':
+    specifier: ^2.2.7
+    version: 2.2.7
+  '@types/lodash':
+    specifier: ^4.14.192
+    version: 4.14.192
+  '@types/node':
+    specifier: ^18.15.11
+    version: 18.15.11
+  '@types/store':
+    specifier: ^2.0.2
+    version: 2.0.2
+  '@vant/use':
+    specifier: ^1.5.1
+    version: 1.5.1(vue@3.2.47)
+  '@vitejs/plugin-legacy':
+    specifier: ^4.0.2
+    version: 4.0.2(terser@5.16.8)(vite@4.2.0)
+  '@vitejs/plugin-vue':
+    specifier: ^4.1.0
+    version: 4.1.0(vite@4.2.0)(vue@3.2.47)
+  '@vitejs/plugin-vue-jsx':
+    specifier: ^3.0.1
+    version: 3.0.1(vite@4.2.0)(vue@3.2.47)
+  canvg:
+    specifier: ^4.0.1
+    version: 4.0.1
+  less:
+    specifier: ^4.1.3
+    version: 4.1.3
+  postcss-pxtorem:
+    specifier: ^6.0.0
+    version: 6.0.0(postcss@8.4.26)
+  terser:
+    specifier: ^5.16.8
+    version: 5.16.8
+  typescript:
+    specifier: ^4.9.3
+    version: 4.9.3
+  unplugin-auto-import:
+    specifier: ^0.16.6
+    version: 0.16.6
+  unplugin-vue-components:
+    specifier: ^0.24.1
+    version: 0.24.1(vue@3.2.47)
+  vite:
+    specifier: ^4.2.0
+    version: 4.2.0(@types/node@18.15.11)(less@4.1.3)(terser@5.16.8)
+  vite-plugin-mkcert:
+    specifier: ^1.15.0
+    version: 1.15.0(vite@4.2.0)
+  vite-plugin-style-import:
+    specifier: ^2.0.0
+    version: 2.0.0(vite@4.2.0)
+  vite-svg-loader:
+    specifier: ^4.0.0
+    version: 4.0.0
+  vue-tsc:
+    specifier: ^1.2.0
+    version: 1.2.0(typescript@4.9.3)
+
+packages:
+
+  /@ampproject/remapping@2.2.1:
+    resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
+    engines: {node: '>=6.0.0'}
+    dependencies:
+      '@jridgewell/gen-mapping': 0.3.3
+      '@jridgewell/trace-mapping': 0.3.18
+    dev: true
+
+  /@antfu/utils@0.7.5:
+    resolution: {integrity: sha512-dlR6LdS+0SzOAPx/TPRhnoi7hE251OVeT2Snw0RguNbBSbjUHdWr0l3vcUUDg26rEysT89kCbtw1lVorBXLLCg==}
+    dev: true
+
+  /@arco-design/color@0.4.0:
+    resolution: {integrity: sha512-s7p9MSwJgHeL8DwcATaXvWT3m2SigKpxx4JA1BGPHL4gfvaQsmQfrLBDpjOJFJuJ2jG2dMt3R3P8Pm9E65q18g==}
+    dependencies:
+      color: 3.2.1
+    dev: false
+
+  /@arco-design/web-vue@2.49.2(vue@3.2.47):
+    resolution: {integrity: sha512-Q/cNVCJgvQWVAGP1yWSlEnvjdZ5emPlJuWfMr23zAQFsgzalYyLY5GZvtIpFtDaZiMXUdnQSTPoK5UTdfdIC9A==}
+    peerDependencies:
+      vue: ^3.1.0
+    dependencies:
+      '@arco-design/color': 0.4.0
+      b-tween: 0.3.3
+      b-validate: 1.5.2
+      compute-scroll-into-view: 1.0.20
+      dayjs: 1.11.7
+      number-precision: 1.6.0
+      resize-observer-polyfill: 1.5.1
+      scroll-into-view-if-needed: 2.2.31
+      vue: 3.2.47
+    dev: false
+
+  /@babel/code-frame@7.22.5:
+    resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/highlight': 7.22.5
+    dev: true
+
+  /@babel/compat-data@7.22.9:
+    resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/core@7.22.9:
+    resolution: {integrity: sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@ampproject/remapping': 2.2.1
+      '@babel/code-frame': 7.22.5
+      '@babel/generator': 7.22.9
+      '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9)
+      '@babel/helpers': 7.22.6
+      '@babel/parser': 7.22.7
+      '@babel/template': 7.22.5
+      '@babel/traverse': 7.22.8
+      '@babel/types': 7.22.5
+      convert-source-map: 1.9.0
+      debug: 4.3.4
+      gensync: 1.0.0-beta.2
+      json5: 2.2.3
+      semver: 6.3.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/generator@7.22.9:
+    resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+      '@jridgewell/gen-mapping': 0.3.3
+      '@jridgewell/trace-mapping': 0.3.18
+      jsesc: 2.5.2
+    dev: true
+
+  /@babel/helper-annotate-as-pure@7.22.5:
+    resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-builder-binary-assignment-operator-visitor@7.22.5:
+    resolution: {integrity: sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-compilation-targets@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/compat-data': 7.22.9
+      '@babel/core': 7.22.9
+      '@babel/helper-validator-option': 7.22.5
+      browserslist: 4.21.9
+      lru-cache: 5.1.1
+      semver: 6.3.1
+    dev: true
+
+  /@babel/helper-create-class-features-plugin@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/helper-function-name': 7.22.5
+      '@babel/helper-member-expression-to-functions': 7.22.5
+      '@babel/helper-optimise-call-expression': 7.22.5
+      '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+      '@babel/helper-split-export-declaration': 7.22.6
+      semver: 6.3.1
+    dev: true
+
+  /@babel/helper-create-regexp-features-plugin@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-annotate-as-pure': 7.22.5
+      regexpu-core: 5.3.2
+      semver: 6.3.1
+    dev: true
+
+  /@babel/helper-define-polyfill-provider@0.4.1(@babel/core@7.22.9):
+    resolution: {integrity: sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A==}
+    peerDependencies:
+      '@babel/core': ^7.4.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      debug: 4.3.4
+      lodash.debounce: 4.0.8
+      resolve: 1.22.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-environment-visitor@7.22.5:
+    resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/helper-function-name@7.22.5:
+    resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/template': 7.22.5
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-hoist-variables@7.22.5:
+    resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-member-expression-to-functions@7.22.5:
+    resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-module-imports@7.22.5:
+    resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/helper-module-imports': 7.22.5
+      '@babel/helper-simple-access': 7.22.5
+      '@babel/helper-split-export-declaration': 7.22.6
+      '@babel/helper-validator-identifier': 7.22.5
+    dev: true
+
+  /@babel/helper-optimise-call-expression@7.22.5:
+    resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-plugin-utils@7.22.5:
+    resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/helper-remap-async-to-generator@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/helper-wrap-function': 7.22.9
+    dev: true
+
+  /@babel/helper-replace-supers@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/helper-member-expression-to-functions': 7.22.5
+      '@babel/helper-optimise-call-expression': 7.22.5
+    dev: true
+
+  /@babel/helper-simple-access@7.22.5:
+    resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-skip-transparent-expression-wrappers@7.22.5:
+    resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-split-export-declaration@7.22.6:
+    resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helper-string-parser@7.22.5:
+    resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/helper-validator-identifier@7.22.5:
+    resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/helper-validator-option@7.22.5:
+    resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/helper-wrap-function@7.22.9:
+    resolution: {integrity: sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-function-name': 7.22.5
+      '@babel/template': 7.22.5
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/helpers@7.22.6:
+    resolution: {integrity: sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/template': 7.22.5
+      '@babel/traverse': 7.22.8
+      '@babel/types': 7.22.5
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/highlight@7.22.5:
+    resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-validator-identifier': 7.22.5
+      chalk: 2.4.2
+      js-tokens: 4.0.0
+    dev: true
+
+  /@babel/parser@7.22.7:
+    resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dependencies:
+      '@babel/types': 7.22.5
+
+  /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.13.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+      '@babel/plugin-transform-optional-chaining': 7.22.6(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.9):
+    resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+    dev: true
+
+  /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.22.9):
+    resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.9):
+    resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.9):
+    resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.9):
+    resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.9):
+    resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.9):
+    resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.9):
+    resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.9):
+    resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.9):
+    resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.9):
+    resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.9):
+    resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.9):
+    resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.9):
+    resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.9):
+    resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-async-generator-functions@7.22.7(@babel/core@7.22.9):
+    resolution: {integrity: sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.9)
+      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-module-imports': 7.22.5
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-block-scoping@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-class-static-block@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.12.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-classes@7.22.6(@babel/core@7.22.9):
+    resolution: {integrity: sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/helper-function-name': 7.22.5
+      '@babel/helper-optimise-call-expression': 7.22.5
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-split-export-declaration': 7.22.6
+      globals: 11.12.0
+    dev: true
+
+  /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/template': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-destructuring@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-dynamic-import@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.5
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-export-namespace-from@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-for-of@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-function-name': 7.22.5
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-json-strings@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-logical-assignment-operators@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-modules-amd@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-modules-commonjs@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-simple-access': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-modules-systemjs@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-hoist-variables': 7.22.5
+      '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-validator-identifier': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-nullish-coalescing-operator@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-numeric-separator@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-object-rest-spread@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.22.9
+      '@babel/core': 7.22.9
+      '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-optional-catch-binding@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-optional-chaining@7.22.6(@babel/core@7.22.9):
+    resolution: {integrity: sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-parameters@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-private-property-in-object@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-regenerator@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      regenerator-transform: 0.15.1
+    dev: true
+
+  /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-typescript@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.9)
+    dev: true
+
+  /@babel/plugin-transform-unicode-escapes@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+    dev: true
+
+  /@babel/preset-env@7.22.9(@babel/core@7.22.9):
+    resolution: {integrity: sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.22.9
+      '@babel/core': 7.22.9
+      '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9)
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/helper-validator-option': 7.22.5
+      '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.9)
+      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9)
+      '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.9)
+      '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9)
+      '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.9)
+      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9)
+      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9)
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9)
+      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9)
+      '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.9)
+      '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.9)
+      '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-async-generator-functions': 7.22.7(@babel/core@7.22.9)
+      '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-class-static-block': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-classes': 7.22.6(@babel/core@7.22.9)
+      '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-dynamic-import': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-export-namespace-from': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-for-of': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-json-strings': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-logical-assignment-operators': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-modules-systemjs': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-nullish-coalescing-operator': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-numeric-separator': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-object-rest-spread': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-optional-catch-binding': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-optional-chaining': 7.22.6(@babel/core@7.22.9)
+      '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-private-property-in-object': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-regenerator': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-unicode-escapes': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.9)
+      '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.9)
+      '@babel/preset-modules': 0.1.5(@babel/core@7.22.9)
+      '@babel/types': 7.22.5
+      babel-plugin-polyfill-corejs2: 0.4.4(@babel/core@7.22.9)
+      babel-plugin-polyfill-corejs3: 0.8.2(@babel/core@7.22.9)
+      babel-plugin-polyfill-regenerator: 0.5.1(@babel/core@7.22.9)
+      core-js-compat: 3.31.1
+      semver: 6.3.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/preset-modules@0.1.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-plugin-utils': 7.22.5
+      '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.22.9)
+      '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.9)
+      '@babel/types': 7.22.5
+      esutils: 2.0.3
+    dev: true
+
+  /@babel/regjsgen@0.8.0:
+    resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==}
+    dev: true
+
+  /@babel/runtime@7.22.6:
+    resolution: {integrity: sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      regenerator-runtime: 0.13.11
+
+  /@babel/template@7.22.5:
+    resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/code-frame': 7.22.5
+      '@babel/parser': 7.22.7
+      '@babel/types': 7.22.5
+    dev: true
+
+  /@babel/traverse@7.22.8:
+    resolution: {integrity: sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/code-frame': 7.22.5
+      '@babel/generator': 7.22.9
+      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/helper-function-name': 7.22.5
+      '@babel/helper-hoist-variables': 7.22.5
+      '@babel/helper-split-export-declaration': 7.22.6
+      '@babel/parser': 7.22.7
+      '@babel/types': 7.22.5
+      debug: 4.3.4
+      globals: 11.12.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/types@7.22.5:
+    resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-string-parser': 7.22.5
+      '@babel/helper-validator-identifier': 7.22.5
+      to-fast-properties: 2.0.0
+
+  /@css-render/plugin-bem@0.15.12(css-render@0.15.12):
+    resolution: {integrity: sha512-Lq2jSOZn+wYQtsyaFj6QRz2EzAnd3iW5fZeHO1WSXQdVYwvwGX0ZiH3X2JQgtgYLT1yeGtrwrqJdNdMEUD2xTw==}
+    peerDependencies:
+      css-render: ~0.15.12
+    dependencies:
+      css-render: 0.15.12
+    dev: false
+
+  /@css-render/vue3-ssr@0.15.12(vue@3.2.47):
+    resolution: {integrity: sha512-AQLGhhaE0F+rwybRCkKUdzBdTEM/5PZBYy+fSYe1T9z9+yxMuV/k7ZRqa4M69X+EI1W8pa4kc9Iq2VjQkZx4rg==}
+    peerDependencies:
+      vue: ^3.0.11
+    dependencies:
+      vue: 3.2.47
+    dev: false
+
+  /@emotion/hash@0.8.0:
+    resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
+    dev: false
+
+  /@esbuild/android-arm64@0.17.19:
+    resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-arm@0.17.19:
+    resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-x64@0.17.19:
+    resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-arm64@0.17.19:
+    resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-x64@0.17.19:
+    resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-arm64@0.17.19:
+    resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-x64@0.17.19:
+    resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm64@0.17.19:
+    resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm@0.17.19:
+    resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ia32@0.17.19:
+    resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-loong64@0.17.19:
+    resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==}
+    engines: {node: '>=12'}
+    cpu: [loong64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-mips64el@0.17.19:
+    resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==}
+    engines: {node: '>=12'}
+    cpu: [mips64el]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ppc64@0.17.19:
+    resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-riscv64@0.17.19:
+    resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==}
+    engines: {node: '>=12'}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-s390x@0.17.19:
+    resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==}
+    engines: {node: '>=12'}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-x64@0.17.19:
+    resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/netbsd-x64@0.17.19:
+    resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [netbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/openbsd-x64@0.17.19:
+    resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [openbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/sunos-x64@0.17.19:
+    resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [sunos]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-arm64@0.17.19:
+    resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-ia32@0.17.19:
+    resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-x64@0.17.19:
+    resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@jridgewell/gen-mapping@0.3.3:
+    resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
+    engines: {node: '>=6.0.0'}
+    dependencies:
+      '@jridgewell/set-array': 1.1.2
+      '@jridgewell/sourcemap-codec': 1.4.15
+      '@jridgewell/trace-mapping': 0.3.18
+    dev: true
+
+  /@jridgewell/resolve-uri@3.1.0:
+    resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
+    engines: {node: '>=6.0.0'}
+    dev: true
+
+  /@jridgewell/set-array@1.1.2:
+    resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
+    engines: {node: '>=6.0.0'}
+    dev: true
+
+  /@jridgewell/source-map@0.3.5:
+    resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
+    dependencies:
+      '@jridgewell/gen-mapping': 0.3.3
+      '@jridgewell/trace-mapping': 0.3.18
+    dev: true
+
+  /@jridgewell/sourcemap-codec@1.4.14:
+    resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
+    dev: true
+
+  /@jridgewell/sourcemap-codec@1.4.15:
+    resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+    dev: true
+
+  /@jridgewell/trace-mapping@0.3.18:
+    resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==}
+    dependencies:
+      '@jridgewell/resolve-uri': 3.1.0
+      '@jridgewell/sourcemap-codec': 1.4.14
+    dev: true
+
+  /@juggle/resize-observer@3.4.0:
+    resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
+    dev: false
+
+  /@nicolo-ribaudo/semver-v6@6.3.3:
+    resolution: {integrity: sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==}
+    hasBin: true
+    dev: true
+
+  /@nodelib/fs.scandir@2.1.5:
+    resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.stat': 2.0.5
+      run-parallel: 1.2.0
+    dev: true
+
+  /@nodelib/fs.stat@2.0.5:
+    resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /@nodelib/fs.walk@1.2.8:
+    resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.scandir': 2.1.5
+      fastq: 1.15.0
+    dev: true
+
+  /@octokit/auth-token@3.0.4:
+    resolution: {integrity: sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==}
+    engines: {node: '>= 14'}
+    dev: true
+
+  /@octokit/core@4.2.4:
+    resolution: {integrity: sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==}
+    engines: {node: '>= 14'}
+    dependencies:
+      '@octokit/auth-token': 3.0.4
+      '@octokit/graphql': 5.0.6
+      '@octokit/request': 6.2.8
+      '@octokit/request-error': 3.0.3
+      '@octokit/types': 9.3.2
+      before-after-hook: 2.2.3
+      universal-user-agent: 6.0.0
+    transitivePeerDependencies:
+      - encoding
+    dev: true
+
+  /@octokit/endpoint@7.0.6:
+    resolution: {integrity: sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==}
+    engines: {node: '>= 14'}
+    dependencies:
+      '@octokit/types': 9.3.2
+      is-plain-object: 5.0.0
+      universal-user-agent: 6.0.0
+    dev: true
+
+  /@octokit/graphql@5.0.6:
+    resolution: {integrity: sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==}
+    engines: {node: '>= 14'}
+    dependencies:
+      '@octokit/request': 6.2.8
+      '@octokit/types': 9.3.2
+      universal-user-agent: 6.0.0
+    transitivePeerDependencies:
+      - encoding
+    dev: true
+
+  /@octokit/openapi-types@18.0.0:
+    resolution: {integrity: sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==}
+    dev: true
+
+  /@octokit/plugin-paginate-rest@6.1.2(@octokit/core@4.2.4):
+    resolution: {integrity: sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==}
+    engines: {node: '>= 14'}
+    peerDependencies:
+      '@octokit/core': '>=4'
+    dependencies:
+      '@octokit/core': 4.2.4
+      '@octokit/tsconfig': 1.0.2
+      '@octokit/types': 9.3.2
+    dev: true
+
+  /@octokit/plugin-request-log@1.0.4(@octokit/core@4.2.4):
+    resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==}
+    peerDependencies:
+      '@octokit/core': '>=3'
+    dependencies:
+      '@octokit/core': 4.2.4
+    dev: true
+
+  /@octokit/plugin-rest-endpoint-methods@7.2.3(@octokit/core@4.2.4):
+    resolution: {integrity: sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==}
+    engines: {node: '>= 14'}
+    peerDependencies:
+      '@octokit/core': '>=3'
+    dependencies:
+      '@octokit/core': 4.2.4
+      '@octokit/types': 10.0.0
+    dev: true
+
+  /@octokit/request-error@3.0.3:
+    resolution: {integrity: sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==}
+    engines: {node: '>= 14'}
+    dependencies:
+      '@octokit/types': 9.3.2
+      deprecation: 2.3.1
+      once: 1.4.0
+    dev: true
+
+  /@octokit/request@6.2.8:
+    resolution: {integrity: sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==}
+    engines: {node: '>= 14'}
+    dependencies:
+      '@octokit/endpoint': 7.0.6
+      '@octokit/request-error': 3.0.3
+      '@octokit/types': 9.3.2
+      is-plain-object: 5.0.0
+      node-fetch: 2.6.12
+      universal-user-agent: 6.0.0
+    transitivePeerDependencies:
+      - encoding
+    dev: true
+
+  /@octokit/rest@19.0.13:
+    resolution: {integrity: sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==}
+    engines: {node: '>= 14'}
+    dependencies:
+      '@octokit/core': 4.2.4
+      '@octokit/plugin-paginate-rest': 6.1.2(@octokit/core@4.2.4)
+      '@octokit/plugin-request-log': 1.0.4(@octokit/core@4.2.4)
+      '@octokit/plugin-rest-endpoint-methods': 7.2.3(@octokit/core@4.2.4)
+    transitivePeerDependencies:
+      - encoding
+    dev: true
+
+  /@octokit/tsconfig@1.0.2:
+    resolution: {integrity: sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==}
+    dev: true
+
+  /@octokit/types@10.0.0:
+    resolution: {integrity: sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==}
+    dependencies:
+      '@octokit/openapi-types': 18.0.0
+    dev: true
+
+  /@octokit/types@9.3.2:
+    resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==}
+    dependencies:
+      '@octokit/openapi-types': 18.0.0
+    dev: true
+
+  /@popperjs/core@2.11.8:
+    resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
+    dev: false
+
+  /@rollup/pluginutils@4.2.1:
+    resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
+    engines: {node: '>= 8.0.0'}
+    dependencies:
+      estree-walker: 2.0.2
+      picomatch: 2.3.1
+    dev: true
+
+  /@rollup/pluginutils@5.0.2:
+    resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
+    engines: {node: '>=14.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0||^3.0.0
+    peerDependenciesMeta:
+      rollup:
+        optional: true
+    dependencies:
+      '@types/estree': 1.0.1
+      estree-walker: 2.0.2
+      picomatch: 2.3.1
+    dev: true
+
+  /@trysound/sax@0.2.0:
+    resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
+    engines: {node: '>=10.13.0'}
+    dev: true
+
+  /@types/estree@1.0.1:
+    resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
+    dev: true
+
+  /@types/howler@2.2.7:
+    resolution: {integrity: sha512-PEZldwZqJJw1PWRTpupyC7ajVTZA8aHd8nB/Y0n6zRZi5u8ktYDntsHj13ltEiBRqWwF06pASxBEvCTxniG8eA==}
+    dev: true
+
+  /@types/katex@0.14.0:
+    resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==}
+    dev: false
+
+  /@types/lodash-es@4.17.8:
+    resolution: {integrity: sha512-euY3XQcZmIzSy7YH5+Unb3b2X12Wtk54YWINBvvGQ5SmMvwb11JQskGsfkH/5HXK77Kr8GF0wkVDIxzAisWtog==}
+    dependencies:
+      '@types/lodash': 4.14.192
+    dev: false
+
+  /@types/lodash@4.14.192:
+    resolution: {integrity: sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==}
+
+  /@types/node@18.15.11:
+    resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==}
+    dev: true
+
+  /@types/offscreencanvas@2019.7.0:
+    resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==}
+    dev: true
+
+  /@types/raf@3.4.0:
+    resolution: {integrity: sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==}
+    dev: true
+
+  /@types/store@2.0.2:
+    resolution: {integrity: sha512-ZPHnXkzmGMfk+pHqAGzTSpA9CbsHmJLgkvOl5w52LZ0XTxB1ZIHWZzQ7lEtjTNWScBbsQekg8TjApMXkMe4nkw==}
+    dev: true
+
+  /@vant/popperjs@1.3.0:
+    resolution: {integrity: sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==}
+    dev: false
+
+  /@vant/touch-emulator@1.4.0:
+    resolution: {integrity: sha512-Zt+zISV0+wpOew2S1siOJ3G22y+hapHAKmXM+FhpvWzsRc4qahaYXatCAITuuXt0EcDp7WvEeTO4F7p9AtX/pw==}
+    dev: false
+
+  /@vant/use@1.5.1(vue@3.2.47):
+    resolution: {integrity: sha512-Zxd7lDz/LliVYEQi3PR9a8CQa/kGCVzF0u9hqDMaTlgXlbG0wHMFPllrcG0ThR6bfs8xrYVuSFM9pJn6HSoUGQ==}
+    peerDependencies:
+      vue: ^3.0.0
+    dependencies:
+      vue: 3.2.47
+
+  /@varlet/icons@2.13.4:
+    resolution: {integrity: sha512-WgLQKA+1KzIpJPneONqpFinXEoyiDt+Zre3zk0zvVm4q27BwKLY93Vzr2a5MsUeKnrLj4r1/rU4B7248ZSqWDQ==}
+    dev: false
+
+  /@varlet/shared@2.13.4:
+    resolution: {integrity: sha512-81mNbzV19Towr4087NXerCMf+yWSFKiWQ0tuPQb1gY8Nw1EMoDUZiAbfpAaPxoOnse5UihvD0SjyOnIhlS8gtg==}
+    dev: false
+
+  /@varlet/touch-emulator@2.13.4:
+    resolution: {integrity: sha512-ila9i9BCGOUqTNZBywuNelfeI+sXMDYi5RwvAmT8cxU0yBvVw/v7POIuRqX/OhWnLer+9DAgzlp87zNDoDj2sA==}
+    dev: false
+
+  /@varlet/ui@2.13.4(vue@3.2.47):
+    resolution: {integrity: sha512-lSB/ZUsOTZVeJAtzxW+yOwnXpjQdOmLSWUsbTPoOuMsQKB8Ex65Ybg7uwJQacpmHmXGAu87mCjB0xrSD6nPjNQ==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      '@popperjs/core': 2.11.8
+      '@varlet/icons': 2.13.4
+      '@varlet/shared': 2.13.4
+      '@varlet/use': 2.13.4(vue@3.2.47)
+      dayjs: 1.11.7
+      decimal.js: 10.4.3
+      vue: 3.2.47
+    dev: false
+
+  /@varlet/use@2.13.4(vue@3.2.47):
+    resolution: {integrity: sha512-+dkpodUBuEJd/tByKLehBTss0HNIHpwiB2nB/oDn7xZi9RKFgYR8qboVpB0R6HulXwd+vgxWckGOPAA1+p3EHw==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      '@varlet/shared': 2.13.4
+      vue: 3.2.47
+    dev: false
+
+  /@vicons/fa@0.12.0:
+    resolution: {integrity: sha512-g2PIeJLsTHUjt6bK63LxqC0uYQB7iu+xViJOxvp1s8b9/akpXVPVWjDTTsP980/0KYyMMe4U7F/aUo7wY+MsXA==}
+    dev: false
+
+  /@vicons/ionicons5@0.12.0:
+    resolution: {integrity: sha512-Iy1EUVRpX0WWxeu1VIReR1zsZLMc4fqpt223czR+Rpnrwu7pt46nbnC2ycO7ItI/uqDLJxnbcMC7FujKs9IfFA==}
+    dev: false
+
+  /@vitejs/plugin-legacy@4.0.2(terser@5.16.8)(vite@4.2.0):
+    resolution: {integrity: sha512-ivnt9sCkgwJTYTWLjuvY6H/HTuiQC1EgzAPkiAvi0yNAssiqOJjyjhG3hAK5LFUUorE0w9kGxn8K0f/74DlbxQ==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    peerDependencies:
+      terser: ^5.4.0
+      vite: ^4.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/preset-env': 7.22.9(@babel/core@7.22.9)
+      browserslist: 4.21.9
+      core-js: 3.31.1
+      magic-string: 0.30.1
+      regenerator-runtime: 0.13.11
+      systemjs: 6.14.1
+      terser: 5.16.8
+      vite: 4.2.0(@types/node@18.15.11)(less@4.1.3)(terser@5.16.8)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@vitejs/plugin-vue-jsx@3.0.1(vite@4.2.0)(vue@3.2.47):
+    resolution: {integrity: sha512-+Jb7ggL48FSPS1uhPnJbJwWa9Sr90vQ+d0InW+AhBM22n+cfuYqJZDckBc+W3QSHe1WDvewMZfa4wZOtk5pRgw==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    peerDependencies:
+      vite: ^4.0.0
+      vue: ^3.0.0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/plugin-transform-typescript': 7.22.9(@babel/core@7.22.9)
+      '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.22.9)
+      vite: 4.2.0(@types/node@18.15.11)(less@4.1.3)(terser@5.16.8)
+      vue: 3.2.47
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@vitejs/plugin-vue@4.1.0(vite@4.2.0)(vue@3.2.47):
+    resolution: {integrity: sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    peerDependencies:
+      vite: ^4.0.0
+      vue: ^3.2.25
+    dependencies:
+      vite: 4.2.0(@types/node@18.15.11)(less@4.1.3)(terser@5.16.8)
+      vue: 3.2.47
+    dev: true
+
+  /@volar/language-core@1.3.0-alpha.0:
+    resolution: {integrity: sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==}
+    dependencies:
+      '@volar/source-map': 1.3.0-alpha.0
+    dev: true
+
+  /@volar/source-map@1.3.0-alpha.0:
+    resolution: {integrity: sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==}
+    dependencies:
+      muggle-string: 0.2.2
+    dev: true
+
+  /@volar/typescript@1.3.0-alpha.0:
+    resolution: {integrity: sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==}
+    dependencies:
+      '@volar/language-core': 1.3.0-alpha.0
+    dev: true
+
+  /@volar/vue-language-core@1.2.0:
+    resolution: {integrity: sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==}
+    dependencies:
+      '@volar/language-core': 1.3.0-alpha.0
+      '@volar/source-map': 1.3.0-alpha.0
+      '@vue/compiler-dom': 3.3.4
+      '@vue/compiler-sfc': 3.3.4
+      '@vue/reactivity': 3.3.4
+      '@vue/shared': 3.3.4
+      minimatch: 6.2.0
+      muggle-string: 0.2.2
+      vue-template-compiler: 2.7.14
+    dev: true
+
+  /@volar/vue-typescript@1.2.0:
+    resolution: {integrity: sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==}
+    dependencies:
+      '@volar/typescript': 1.3.0-alpha.0
+      '@volar/vue-language-core': 1.2.0
+    dev: true
+
+  /@vue/babel-helper-vue-transform-on@1.1.5:
+    resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==}
+    dev: true
+
+  /@vue/babel-plugin-jsx@1.1.5(@babel/core@7.22.9):
+    resolution: {integrity: sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-module-imports': 7.22.5
+      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.9)
+      '@babel/template': 7.22.5
+      '@babel/traverse': 7.22.8
+      '@babel/types': 7.22.5
+      '@vue/babel-helper-vue-transform-on': 1.1.5
+      camelcase: 6.3.0
+      html-tags: 3.3.1
+      svg-tags: 1.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@vue/compiler-core@3.2.47:
+    resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==}
+    dependencies:
+      '@babel/parser': 7.22.7
+      '@vue/shared': 3.2.47
+      estree-walker: 2.0.2
+      source-map: 0.6.1
+
+  /@vue/compiler-core@3.3.4:
+    resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==}
+    dependencies:
+      '@babel/parser': 7.22.7
+      '@vue/shared': 3.3.4
+      estree-walker: 2.0.2
+      source-map-js: 1.0.2
+    dev: true
+
+  /@vue/compiler-dom@3.2.47:
+    resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==}
+    dependencies:
+      '@vue/compiler-core': 3.2.47
+      '@vue/shared': 3.2.47
+
+  /@vue/compiler-dom@3.3.4:
+    resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==}
+    dependencies:
+      '@vue/compiler-core': 3.3.4
+      '@vue/shared': 3.3.4
+    dev: true
+
+  /@vue/compiler-sfc@3.2.47:
+    resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==}
+    dependencies:
+      '@babel/parser': 7.22.7
+      '@vue/compiler-core': 3.2.47
+      '@vue/compiler-dom': 3.2.47
+      '@vue/compiler-ssr': 3.2.47
+      '@vue/reactivity-transform': 3.2.47
+      '@vue/shared': 3.2.47
+      estree-walker: 2.0.2
+      magic-string: 0.25.9
+      postcss: 8.4.26
+      source-map: 0.6.1
+
+  /@vue/compiler-sfc@3.3.4:
+    resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==}
+    dependencies:
+      '@babel/parser': 7.22.7
+      '@vue/compiler-core': 3.3.4
+      '@vue/compiler-dom': 3.3.4
+      '@vue/compiler-ssr': 3.3.4
+      '@vue/reactivity-transform': 3.3.4
+      '@vue/shared': 3.3.4
+      estree-walker: 2.0.2
+      magic-string: 0.30.1
+      postcss: 8.4.26
+      source-map-js: 1.0.2
+    dev: true
+
+  /@vue/compiler-ssr@3.2.47:
+    resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==}
+    dependencies:
+      '@vue/compiler-dom': 3.2.47
+      '@vue/shared': 3.2.47
+
+  /@vue/compiler-ssr@3.3.4:
+    resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==}
+    dependencies:
+      '@vue/compiler-dom': 3.3.4
+      '@vue/shared': 3.3.4
+    dev: true
+
+  /@vue/devtools-api@6.5.0:
+    resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
+    dev: false
+
+  /@vue/reactivity-transform@3.2.47:
+    resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==}
+    dependencies:
+      '@babel/parser': 7.22.7
+      '@vue/compiler-core': 3.2.47
+      '@vue/shared': 3.2.47
+      estree-walker: 2.0.2
+      magic-string: 0.25.9
+
+  /@vue/reactivity-transform@3.3.4:
+    resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==}
+    dependencies:
+      '@babel/parser': 7.22.7
+      '@vue/compiler-core': 3.3.4
+      '@vue/shared': 3.3.4
+      estree-walker: 2.0.2
+      magic-string: 0.30.1
+    dev: true
+
+  /@vue/reactivity@3.2.47:
+    resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==}
+    dependencies:
+      '@vue/shared': 3.2.47
+
+  /@vue/reactivity@3.3.4:
+    resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==}
+    dependencies:
+      '@vue/shared': 3.3.4
+    dev: true
+
+  /@vue/runtime-core@3.2.47:
+    resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==}
+    dependencies:
+      '@vue/reactivity': 3.2.47
+      '@vue/shared': 3.2.47
+
+  /@vue/runtime-dom@3.2.47:
+    resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==}
+    dependencies:
+      '@vue/runtime-core': 3.2.47
+      '@vue/shared': 3.2.47
+      csstype: 2.6.21
+
+  /@vue/server-renderer@3.2.47(vue@3.2.47):
+    resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==}
+    peerDependencies:
+      vue: 3.2.47
+    dependencies:
+      '@vue/compiler-ssr': 3.2.47
+      '@vue/shared': 3.2.47
+      vue: 3.2.47
+
+  /@vue/shared@3.2.47:
+    resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==}
+
+  /@vue/shared@3.3.4:
+    resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
+    dev: true
+
+  /abcjs@6.2.2:
+    resolution: {integrity: sha512-M5pvTb+0yABqScZBEN/bZmrMgX+iTtgD8vxAVTaKNNVt+ivyCzx0SLNYlTXYErlXu7QvPIoIiSPRojne6M24PA==}
+    dev: false
+
+  /acorn@8.10.0:
+    resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /ansi-styles@3.2.1:
+    resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+    engines: {node: '>=4'}
+    dependencies:
+      color-convert: 1.9.3
+    dev: true
+
+  /anymatch@3.1.3:
+    resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+    engines: {node: '>= 8'}
+    dependencies:
+      normalize-path: 3.0.0
+      picomatch: 2.3.1
+    dev: true
+
+  /async-validator@4.2.5:
+    resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
+    dev: false
+
+  /asynckit@0.4.0:
+    resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+    dev: true
+
+  /axios@1.4.0(debug@4.3.4):
+    resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==}
+    dependencies:
+      follow-redirects: 1.15.2(debug@4.3.4)
+      form-data: 4.0.0
+      proxy-from-env: 1.1.0
+    transitivePeerDependencies:
+      - debug
+    dev: true
+
+  /b-tween@0.3.3:
+    resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==}
+    dev: false
+
+  /b-validate@1.5.2:
+    resolution: {integrity: sha512-zhIdocs1x9fJYBMc5Qe2kS3iJv8oRA55S3vV9ucdX+//ySV17PVuGGtwl6lwbbNvdjUt3Pt6ujL0GaVsXJy2ZA==}
+    dev: false
+
+  /babel-plugin-polyfill-corejs2@0.4.4(@babel/core@7.22.9):
+    resolution: {integrity: sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.22.9
+      '@babel/core': 7.22.9
+      '@babel/helper-define-polyfill-provider': 0.4.1(@babel/core@7.22.9)
+      '@nicolo-ribaudo/semver-v6': 6.3.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs3@0.8.2(@babel/core@7.22.9):
+    resolution: {integrity: sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-define-polyfill-provider': 0.4.1(@babel/core@7.22.9)
+      core-js-compat: 3.31.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-regenerator@0.5.1(@babel/core@7.22.9):
+    resolution: {integrity: sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.22.9
+      '@babel/helper-define-polyfill-provider': 0.4.1(@babel/core@7.22.9)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /balanced-match@1.0.2:
+    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+    dev: true
+
+  /base64-arraybuffer@1.0.2:
+    resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
+    engines: {node: '>= 0.6.0'}
+    dev: false
+
+  /before-after-hook@2.2.3:
+    resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
+    dev: true
+
+  /binary-extensions@2.2.0:
+    resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /boolbase@1.0.0:
+    resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+    dev: true
+
+  /brace-expansion@2.0.1:
+    resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+    dependencies:
+      balanced-match: 1.0.2
+    dev: true
+
+  /braces@3.0.2:
+    resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+    engines: {node: '>=8'}
+    dependencies:
+      fill-range: 7.0.1
+    dev: true
+
+  /browserslist@4.21.9:
+    resolution: {integrity: sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==}
+    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+    hasBin: true
+    dependencies:
+      caniuse-lite: 1.0.30001516
+      electron-to-chromium: 1.4.463
+      node-releases: 2.0.13
+      update-browserslist-db: 1.0.11(browserslist@4.21.9)
+    dev: true
+
+  /buffer-from@1.1.2:
+    resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+    dev: true
+
+  /call-bind@1.0.2:
+    resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+    dependencies:
+      function-bind: 1.1.1
+      get-intrinsic: 1.2.1
+    dev: false
+
+  /camel-case@4.1.2:
+    resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
+    dependencies:
+      pascal-case: 3.1.2
+      tslib: 2.6.0
+    dev: true
+
+  /camelcase@6.3.0:
+    resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /caniuse-lite@1.0.30001516:
+    resolution: {integrity: sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==}
+    dev: true
+
+  /canvg@4.0.1:
+    resolution: {integrity: sha512-5gD/d6SiCCT7baLnVr0hokYe93DfcHW2rSqdKOuOQD84YMlyfttnZ8iQsThTdX6koYam+PROz/FuQTo500zqGw==}
+    engines: {node: '>=12.0.0'}
+    dependencies:
+      '@types/offscreencanvas': 2019.7.0
+      '@types/raf': 3.4.0
+      raf: 3.4.1
+      rgbcolor: 1.0.1
+      stackblur-canvas: 2.6.0
+      svg-pathdata: 6.0.3
+    dev: true
+
+  /capital-case@1.0.4:
+    resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.6.0
+      upper-case-first: 2.0.2
+    dev: true
+
+  /chalk@2.4.2:
+    resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      ansi-styles: 3.2.1
+      escape-string-regexp: 1.0.5
+      supports-color: 5.5.0
+    dev: true
+
+  /change-case@4.1.2:
+    resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==}
+    dependencies:
+      camel-case: 4.1.2
+      capital-case: 1.0.4
+      constant-case: 3.0.4
+      dot-case: 3.0.4
+      header-case: 2.0.4
+      no-case: 3.0.4
+      param-case: 3.0.4
+      pascal-case: 3.1.2
+      path-case: 3.0.4
+      sentence-case: 3.0.4
+      snake-case: 3.0.4
+      tslib: 2.6.0
+    dev: true
+
+  /chokidar@3.5.3:
+    resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+    engines: {node: '>= 8.10.0'}
+    dependencies:
+      anymatch: 3.1.3
+      braces: 3.0.2
+      glob-parent: 5.1.2
+      is-binary-path: 2.1.0
+      is-glob: 4.0.3
+      normalize-path: 3.0.0
+      readdirp: 3.6.0
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /clean-deep@3.4.0:
+    resolution: {integrity: sha512-Lo78NV5ItJL/jl+B5w0BycAisaieJGXK1qYi/9m4SjR8zbqmrUtO7Yhro40wEShGmmxs/aJLI/A+jNhdkXK8mw==}
+    engines: {node: '>=4'}
+    dependencies:
+      lodash.isempty: 4.4.0
+      lodash.isplainobject: 4.0.6
+      lodash.transform: 4.6.0
+    dev: false
+
+  /color-convert@1.9.3:
+    resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+    dependencies:
+      color-name: 1.1.3
+
+  /color-name@1.1.3:
+    resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+
+  /color-string@1.9.1:
+    resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+    dependencies:
+      color-name: 1.1.3
+      simple-swizzle: 0.2.2
+    dev: false
+
+  /color@3.2.1:
+    resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
+    dependencies:
+      color-convert: 1.9.3
+      color-string: 1.9.1
+    dev: false
+
+  /combined-stream@1.0.8:
+    resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      delayed-stream: 1.0.0
+    dev: true
+
+  /commander@2.20.3:
+    resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+    dev: true
+
+  /commander@7.2.0:
+    resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
+    engines: {node: '>= 10'}
+    dev: true
+
+  /compute-scroll-into-view@1.0.20:
+    resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
+    dev: false
+
+  /consola@2.15.3:
+    resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
+    dev: false
+
+  /console@0.7.2:
+    resolution: {integrity: sha512-+JSDwGunA4MTEgAV/4VBKwUHonP8CzJ/6GIuwPi6acKFqFfHUdSGCm89ZxZ5FfGWdZfkdgAroy5bJ5FSeN/t4g==}
+    dev: true
+
+  /constant-case@3.0.4:
+    resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.6.0
+      upper-case: 2.0.2
+    dev: true
+
+  /convert-source-map@1.9.0:
+    resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
+    dev: true
+
+  /copy-anything@2.0.6:
+    resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
+    dependencies:
+      is-what: 3.14.1
+    dev: true
+
+  /core-js-compat@3.31.1:
+    resolution: {integrity: sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==}
+    dependencies:
+      browserslist: 4.21.9
+    dev: true
+
+  /core-js@3.31.1:
+    resolution: {integrity: sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ==}
+    requiresBuild: true
+
+  /css-line-break@2.1.0:
+    resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
+    dependencies:
+      utrie: 1.0.2
+    dev: false
+
+  /css-render@0.15.12:
+    resolution: {integrity: sha512-eWzS66patiGkTTik+ipO9qNGZ+uNuGyTmnz6/+EJIiFg8+3yZRpnMwgFo8YdXhQRsiePzehnusrxVvugNjXzbw==}
+    dependencies:
+      '@emotion/hash': 0.8.0
+      csstype: 3.0.11
+    dev: false
+
+  /css-select@5.1.0:
+    resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
+    dependencies:
+      boolbase: 1.0.0
+      css-what: 6.1.0
+      domhandler: 5.0.3
+      domutils: 3.1.0
+      nth-check: 2.1.1
+    dev: true
+
+  /css-tree@2.2.1:
+    resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
+    engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+    dependencies:
+      mdn-data: 2.0.28
+      source-map-js: 1.0.2
+    dev: true
+
+  /css-tree@2.3.1:
+    resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
+    engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+    dependencies:
+      mdn-data: 2.0.30
+      source-map-js: 1.0.2
+    dev: true
+
+  /css-what@6.1.0:
+    resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /csso@5.0.5:
+    resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
+    engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+    dependencies:
+      css-tree: 2.2.1
+    dev: true
+
+  /csstype@2.6.21:
+    resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
+
+  /csstype@3.0.11:
+    resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==}
+    dev: false
+
+  /custom-event-polyfill@1.0.7:
+    resolution: {integrity: sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==}
+    dev: false
+
+  /date-fns-tz@1.3.8(date-fns@2.30.0):
+    resolution: {integrity: sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==}
+    peerDependencies:
+      date-fns: '>=2.0.0'
+    dependencies:
+      date-fns: 2.30.0
+    dev: false
+
+  /date-fns@2.30.0:
+    resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
+    engines: {node: '>=0.11'}
+    dependencies:
+      '@babel/runtime': 7.22.6
+    dev: false
+
+  /dayjs@1.11.7:
+    resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==}
+    dev: false
+
+  /de-indent@1.0.2:
+    resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+    dev: true
+
+  /debug@3.2.7:
+    resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.3
+    dev: true
+    optional: true
+
+  /debug@4.3.4:
+    resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.2
+    dev: true
+
+  /decimal.js@10.4.3:
+    resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
+    dev: false
+
+  /decode-uri-component@0.4.1:
+    resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==}
+    engines: {node: '>=14.16'}
+    dev: false
+
+  /delayed-stream@1.0.0:
+    resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+    engines: {node: '>=0.4.0'}
+    dev: true
+
+  /deprecation@2.3.1:
+    resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
+    dev: true
+
+  /dom-serializer@2.0.0:
+    resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+    dependencies:
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+      entities: 4.5.0
+    dev: true
+
+  /domelementtype@2.3.0:
+    resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+    dev: true
+
+  /domhandler@5.0.3:
+    resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+    engines: {node: '>= 4'}
+    dependencies:
+      domelementtype: 2.3.0
+    dev: true
+
+  /domutils@3.1.0:
+    resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
+    dependencies:
+      dom-serializer: 2.0.0
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+    dev: true
+
+  /dot-case@3.0.4:
+    resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.6.0
+    dev: true
+
+  /electron-to-chromium@1.4.463:
+    resolution: {integrity: sha512-fT3hvdUWLjDbaTGzyOjng/CQhQJSQP8ThO3XZAoaxHvHo2kUXiRQVMj9M235l8uDFiNPsPa6KHT1p3RaR6ugRw==}
+    dev: true
+
+  /encoding@0.1.13:
+    resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
+    dependencies:
+      iconv-lite: 0.6.3
+    dev: false
+
+  /entities@4.5.0:
+    resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+    engines: {node: '>=0.12'}
+    dev: true
+
+  /errno@0.1.8:
+    resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
+    hasBin: true
+    requiresBuild: true
+    dependencies:
+      prr: 1.0.1
+    dev: true
+    optional: true
+
+  /es-module-lexer@0.9.3:
+    resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==}
+    dev: true
+
+  /esbuild@0.17.19:
+    resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==}
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    optionalDependencies:
+      '@esbuild/android-arm': 0.17.19
+      '@esbuild/android-arm64': 0.17.19
+      '@esbuild/android-x64': 0.17.19
+      '@esbuild/darwin-arm64': 0.17.19
+      '@esbuild/darwin-x64': 0.17.19
+      '@esbuild/freebsd-arm64': 0.17.19
+      '@esbuild/freebsd-x64': 0.17.19
+      '@esbuild/linux-arm': 0.17.19
+      '@esbuild/linux-arm64': 0.17.19
+      '@esbuild/linux-ia32': 0.17.19
+      '@esbuild/linux-loong64': 0.17.19
+      '@esbuild/linux-mips64el': 0.17.19
+      '@esbuild/linux-ppc64': 0.17.19
+      '@esbuild/linux-riscv64': 0.17.19
+      '@esbuild/linux-s390x': 0.17.19
+      '@esbuild/linux-x64': 0.17.19
+      '@esbuild/netbsd-x64': 0.17.19
+      '@esbuild/openbsd-x64': 0.17.19
+      '@esbuild/sunos-x64': 0.17.19
+      '@esbuild/win32-arm64': 0.17.19
+      '@esbuild/win32-ia32': 0.17.19
+      '@esbuild/win32-x64': 0.17.19
+    dev: true
+
+  /escalade@3.1.1:
+    resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /escape-string-regexp@1.0.5:
+    resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+    engines: {node: '>=0.8.0'}
+    dev: true
+
+  /escape-string-regexp@5.0.0:
+    resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+    engines: {node: '>=12'}
+    dev: true
+
+  /estree-walker@2.0.2:
+    resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+  /esutils@2.0.3:
+    resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /eventemitter3@5.0.0:
+    resolution: {integrity: sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg==}
+    dev: false
+
+  /evtd@0.2.4:
+    resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==}
+    dev: false
+
+  /fast-glob@3.3.0:
+    resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==}
+    engines: {node: '>=8.6.0'}
+    dependencies:
+      '@nodelib/fs.stat': 2.0.5
+      '@nodelib/fs.walk': 1.2.8
+      glob-parent: 5.1.2
+      merge2: 1.4.1
+      micromatch: 4.0.5
+    dev: true
+
+  /fastq@1.15.0:
+    resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+    dependencies:
+      reusify: 1.0.4
+    dev: true
+
+  /fill-range@7.0.1:
+    resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      to-regex-range: 5.0.1
+    dev: true
+
+  /filter-obj@5.1.0:
+    resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==}
+    engines: {node: '>=14.16'}
+    dev: false
+
+  /follow-redirects@1.15.2(debug@4.3.4):
+    resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
+    engines: {node: '>=4.0'}
+    peerDependencies:
+      debug: '*'
+    peerDependenciesMeta:
+      debug:
+        optional: true
+    dependencies:
+      debug: 4.3.4
+    dev: true
+
+  /form-data@4.0.0:
+    resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+    engines: {node: '>= 6'}
+    dependencies:
+      asynckit: 0.4.0
+      combined-stream: 1.0.8
+      mime-types: 2.1.35
+    dev: true
+
+  /fs-extra@10.1.0:
+    resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
+    engines: {node: '>=12'}
+    dependencies:
+      graceful-fs: 4.2.11
+      jsonfile: 6.1.0
+      universalify: 2.0.0
+    dev: true
+
+  /fsevents@2.3.2:
+    resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /function-bind@1.1.1:
+    resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+
+  /gensync@1.0.0-beta.2:
+    resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /get-intrinsic@1.2.1:
+    resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
+    dependencies:
+      function-bind: 1.1.1
+      has: 1.0.3
+      has-proto: 1.0.1
+      has-symbols: 1.0.3
+    dev: false
+
+  /glob-parent@5.1.2:
+    resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+    engines: {node: '>= 6'}
+    dependencies:
+      is-glob: 4.0.3
+    dev: true
+
+  /globals@11.12.0:
+    resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /graceful-fs@4.2.11:
+    resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+    dev: true
+
+  /has-flag@3.0.0:
+    resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /has-proto@1.0.1:
+    resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
+    engines: {node: '>= 0.4'}
+    dev: false
+
+  /has-symbols@1.0.3:
+    resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+    engines: {node: '>= 0.4'}
+    dev: false
+
+  /has@1.0.3:
+    resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+    engines: {node: '>= 0.4.0'}
+    dependencies:
+      function-bind: 1.1.1
+
+  /he@1.2.0:
+    resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+    hasBin: true
+    dev: true
+
+  /header-case@2.0.4:
+    resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==}
+    dependencies:
+      capital-case: 1.0.4
+      tslib: 2.6.0
+    dev: true
+
+  /highlight.js@11.8.0:
+    resolution: {integrity: sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==}
+    engines: {node: '>=12.0.0'}
+    dev: false
+
+  /howler@2.2.3:
+    resolution: {integrity: sha512-QM0FFkw0LRX1PR8pNzJVAY25JhIWvbKMBFM4gqk+QdV+kPXOhleWGCB6AiAF/goGjIHK2e/nIElplvjQwhr0jg==}
+    dev: false
+
+  /html-tags@3.3.1:
+    resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /html2canvas@1.4.1:
+    resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      css-line-break: 2.1.0
+      text-segmentation: 1.0.3
+    dev: false
+
+  /iconv-lite@0.6.3:
+    resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      safer-buffer: 2.1.2
+
+  /image-size@0.5.5:
+    resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
+    engines: {node: '>=0.10.0'}
+    hasBin: true
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /is-arrayish@0.3.2:
+    resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+    dev: false
+
+  /is-binary-path@2.1.0:
+    resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+    engines: {node: '>=8'}
+    dependencies:
+      binary-extensions: 2.2.0
+    dev: true
+
+  /is-core-module@2.12.1:
+    resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==}
+    dependencies:
+      has: 1.0.3
+    dev: true
+
+  /is-extglob@2.1.1:
+    resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /is-glob@4.0.3:
+    resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extglob: 2.1.1
+    dev: true
+
+  /is-number@7.0.0:
+    resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+    engines: {node: '>=0.12.0'}
+    dev: true
+
+  /is-plain-object@5.0.0:
+    resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /is-stream@1.1.0:
+    resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==}
+    engines: {node: '>=0.10.0'}
+    dev: false
+
+  /is-what@3.14.1:
+    resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
+    dev: true
+
+  /isomorphic-fetch@2.2.1:
+    resolution: {integrity: sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==}
+    dependencies:
+      node-fetch: 1.7.3
+      whatwg-fetch: 3.6.2
+    dev: false
+
+  /js-tokens@4.0.0:
+    resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+    dev: true
+
+  /jsesc@0.5.0:
+    resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==}
+    hasBin: true
+    dev: true
+
+  /jsesc@2.5.2:
+    resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dev: true
+
+  /json5@2.2.3:
+    resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+    engines: {node: '>=6'}
+    hasBin: true
+    dev: true
+
+  /jsonc-parser@3.2.0:
+    resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
+    dev: true
+
+  /jsonfile@6.1.0:
+    resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+    dependencies:
+      universalify: 2.0.0
+    optionalDependencies:
+      graceful-fs: 4.2.11
+    dev: true
+
+  /less@4.1.3:
+    resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==}
+    engines: {node: '>=6'}
+    hasBin: true
+    dependencies:
+      copy-anything: 2.0.6
+      parse-node-version: 1.0.1
+      tslib: 2.6.0
+    optionalDependencies:
+      errno: 0.1.8
+      graceful-fs: 4.2.11
+      image-size: 0.5.5
+      make-dir: 2.1.0
+      mime: 1.6.0
+      needle: 3.2.0
+      source-map: 0.6.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /loadjs@4.2.0:
+    resolution: {integrity: sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA==}
+    dev: false
+
+  /local-pkg@0.4.3:
+    resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
+    engines: {node: '>=14'}
+    dev: true
+
+  /lodash-es@4.17.21:
+    resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+    dev: false
+
+  /lodash.debounce@4.0.8:
+    resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
+    dev: true
+
+  /lodash.isempty@4.4.0:
+    resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==}
+    dev: false
+
+  /lodash.isplainobject@4.0.6:
+    resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
+    dev: false
+
+  /lodash.transform@4.6.0:
+    resolution: {integrity: sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==}
+    dev: false
+
+  /lodash@4.17.21:
+    resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+    dev: false
+
+  /lottie-web@5.12.2:
+    resolution: {integrity: sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==}
+    dev: false
+
+  /lower-case@2.0.2:
+    resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+    dependencies:
+      tslib: 2.6.0
+    dev: true
+
+  /lru-cache@5.1.1:
+    resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+    dependencies:
+      yallist: 3.1.1
+    dev: true
+
+  /magic-string@0.25.9:
+    resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
+    dependencies:
+      sourcemap-codec: 1.4.8
+
+  /magic-string@0.30.1:
+    resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==}
+    engines: {node: '>=12'}
+    dependencies:
+      '@jridgewell/sourcemap-codec': 1.4.15
+    dev: true
+
+  /make-dir@2.1.0:
+    resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
+    engines: {node: '>=6'}
+    requiresBuild: true
+    dependencies:
+      pify: 4.0.1
+      semver: 5.7.2
+    dev: true
+    optional: true
+
+  /mdn-data@2.0.28:
+    resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
+    dev: true
+
+  /mdn-data@2.0.30:
+    resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
+    dev: true
+
+  /merge2@1.4.1:
+    resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /micromatch@4.0.5:
+    resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+    engines: {node: '>=8.6'}
+    dependencies:
+      braces: 3.0.2
+      picomatch: 2.3.1
+    dev: true
+
+  /mime-db@1.52.0:
+    resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+    engines: {node: '>= 0.6'}
+    dev: true
+
+  /mime-types@2.1.35:
+    resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-db: 1.52.0
+    dev: true
+
+  /mime@1.6.0:
+    resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+    engines: {node: '>=4'}
+    hasBin: true
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /minimatch@6.2.0:
+    resolution: {integrity: sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==}
+    engines: {node: '>=10'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: true
+
+  /minimatch@7.4.6:
+    resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==}
+    engines: {node: '>=10'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: true
+
+  /minimatch@9.0.3:
+    resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
+    engines: {node: '>=16 || 14 >=14.17'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: true
+
+  /mlly@1.4.0:
+    resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
+    dependencies:
+      acorn: 8.10.0
+      pathe: 1.1.1
+      pkg-types: 1.0.3
+      ufo: 1.1.2
+    dev: true
+
+  /ms@2.1.2:
+    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+    dev: true
+
+  /ms@2.1.3:
+    resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+    dev: true
+    optional: true
+
+  /muggle-string@0.2.2:
+    resolution: {integrity: sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==}
+    dev: true
+
+  /naive-ui@2.34.4(vue@3.2.47):
+    resolution: {integrity: sha512-aPG8PDfhSzIzn/jSC9y3Jb3Pe2wHJ7F0cFV1EWlbImSrZECeUmoc+fIcOSWbizoztkKfaUAeKwYdMl09MKkj1g==}
+    peerDependencies:
+      vue: ^3.0.0
+    dependencies:
+      '@css-render/plugin-bem': 0.15.12(css-render@0.15.12)
+      '@css-render/vue3-ssr': 0.15.12(vue@3.2.47)
+      '@types/katex': 0.14.0
+      '@types/lodash': 4.14.192
+      '@types/lodash-es': 4.17.8
+      async-validator: 4.2.5
+      css-render: 0.15.12
+      date-fns: 2.30.0
+      date-fns-tz: 1.3.8(date-fns@2.30.0)
+      evtd: 0.2.4
+      highlight.js: 11.8.0
+      lodash: 4.17.21
+      lodash-es: 4.17.21
+      seemly: 0.3.6
+      treemate: 0.3.11
+      vdirs: 0.1.8(vue@3.2.47)
+      vooks: 0.2.12(vue@3.2.47)
+      vue: 3.2.47
+      vueuc: 0.4.51(vue@3.2.47)
+    dev: false
+
+  /nanoid@3.3.6:
+    resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+
+  /needle@3.2.0:
+    resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==}
+    engines: {node: '>= 4.4.x'}
+    hasBin: true
+    requiresBuild: true
+    dependencies:
+      debug: 3.2.7
+      iconv-lite: 0.6.3
+      sax: 1.2.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+    optional: true
+
+  /no-case@3.0.4:
+    resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+    dependencies:
+      lower-case: 2.0.2
+      tslib: 2.6.0
+    dev: true
+
+  /node-fetch@1.7.3:
+    resolution: {integrity: sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==}
+    dependencies:
+      encoding: 0.1.13
+      is-stream: 1.1.0
+    dev: false
+
+  /node-fetch@2.6.12:
+    resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==}
+    engines: {node: 4.x || >=6.0.0}
+    peerDependencies:
+      encoding: ^0.1.0
+    peerDependenciesMeta:
+      encoding:
+        optional: true
+    dependencies:
+      whatwg-url: 5.0.0
+    dev: true
+
+  /node-releases@2.0.13:
+    resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
+    dev: true
+
+  /normalize-path@3.0.0:
+    resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /nth-check@2.1.1:
+    resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+    dependencies:
+      boolbase: 1.0.0
+    dev: true
+
+  /number-precision@1.6.0:
+    resolution: {integrity: sha512-05OLPgbgmnixJw+VvEh18yNPUo3iyp4BEWJcrLu4X9W05KmMifN7Mu5exYvQXqxxeNWhvIF+j3Rij+HmddM/hQ==}
+    dev: false
+
+  /object-inspect@1.12.3:
+    resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
+    dev: false
+
+  /once@1.4.0:
+    resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+    dependencies:
+      wrappy: 1.0.2
+    dev: true
+
+  /param-case@3.0.4:
+    resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
+    dependencies:
+      dot-case: 3.0.4
+      tslib: 2.6.0
+    dev: true
+
+  /parse-node-version@1.0.1:
+    resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
+    engines: {node: '>= 0.10'}
+    dev: true
+
+  /pascal-case@3.1.2:
+    resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.6.0
+    dev: true
+
+  /path-case@3.0.4:
+    resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==}
+    dependencies:
+      dot-case: 3.0.4
+      tslib: 2.6.0
+    dev: true
+
+  /path-parse@1.0.7:
+    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+    dev: true
+
+  /pathe@0.2.0:
+    resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==}
+    dev: true
+
+  /pathe@1.1.1:
+    resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
+    dev: true
+
+  /performance-now@2.1.0:
+    resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
+    dev: true
+
+  /picocolors@1.0.0:
+    resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+
+  /picomatch@2.3.1:
+    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+    engines: {node: '>=8.6'}
+    dev: true
+
+  /pify@4.0.1:
+    resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
+    engines: {node: '>=6'}
+    dev: true
+    optional: true
+
+  /pkg-types@1.0.3:
+    resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
+    dependencies:
+      jsonc-parser: 3.2.0
+      mlly: 1.4.0
+      pathe: 1.1.1
+    dev: true
+
+  /plyr@3.7.8:
+    resolution: {integrity: sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==}
+    dependencies:
+      core-js: 3.31.1
+      custom-event-polyfill: 1.0.7
+      loadjs: 4.2.0
+      rangetouch: 2.0.1
+      url-polyfill: 1.1.12
+    dev: false
+
+  /postcss-pxtorem@6.0.0(postcss@8.4.26):
+    resolution: {integrity: sha512-ZRXrD7MLLjLk2RNGV6UA4f5Y7gy+a/j1EqjAfp9NdcNYVjUMvg5HTYduTjSkKBkRkfqbg/iKrjMO70V4g1LZeg==}
+    peerDependencies:
+      postcss: ^8.0.0
+    dependencies:
+      postcss: 8.4.26
+    dev: true
+
+  /postcss@8.4.26:
+    resolution: {integrity: sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: 3.3.6
+      picocolors: 1.0.0
+      source-map-js: 1.0.2
+
+  /proxy-from-env@1.1.0:
+    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+    dev: true
+
+  /prr@1.0.1:
+    resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
+    dev: true
+    optional: true
+
+  /qs@6.11.2:
+    resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==}
+    engines: {node: '>=0.6'}
+    dependencies:
+      side-channel: 1.0.4
+    dev: false
+
+  /query-string@8.1.0:
+    resolution: {integrity: sha512-BFQeWxJOZxZGix7y+SByG3F36dA0AbTy9o6pSmKFcFz7DAj0re9Frkty3saBn3nHo3D0oZJ/+rx3r8H8r8Jbpw==}
+    engines: {node: '>=14.16'}
+    dependencies:
+      decode-uri-component: 0.4.1
+      filter-obj: 5.1.0
+      split-on-first: 3.0.0
+    dev: false
+
+  /queue-microtask@1.2.3:
+    resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+    dev: true
+
+  /raf@3.4.1:
+    resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
+    dependencies:
+      performance-now: 2.1.0
+    dev: true
+
+  /rangetouch@2.0.1:
+    resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==}
+    dev: false
+
+  /readdirp@3.6.0:
+    resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+    engines: {node: '>=8.10.0'}
+    dependencies:
+      picomatch: 2.3.1
+    dev: true
+
+  /regenerate-unicode-properties@10.1.0:
+    resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      regenerate: 1.4.2
+    dev: true
+
+  /regenerate@1.4.2:
+    resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==}
+    dev: true
+
+  /regenerator-runtime@0.13.11:
+    resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
+
+  /regenerator-transform@0.15.1:
+    resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==}
+    dependencies:
+      '@babel/runtime': 7.22.6
+    dev: true
+
+  /regexpu-core@5.3.2:
+    resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      '@babel/regjsgen': 0.8.0
+      regenerate: 1.4.2
+      regenerate-unicode-properties: 10.1.0
+      regjsparser: 0.9.1
+      unicode-match-property-ecmascript: 2.0.0
+      unicode-match-property-value-ecmascript: 2.1.0
+    dev: true
+
+  /regjsparser@0.9.1:
+    resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==}
+    hasBin: true
+    dependencies:
+      jsesc: 0.5.0
+    dev: true
+
+  /resize-observer-polyfill@1.5.1:
+    resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
+    dev: false
+
+  /resolve@1.22.2:
+    resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
+    hasBin: true
+    dependencies:
+      is-core-module: 2.12.1
+      path-parse: 1.0.7
+      supports-preserve-symlinks-flag: 1.0.0
+    dev: true
+
+  /reusify@1.0.4:
+    resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+    engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+    dev: true
+
+  /rgbcolor@1.0.1:
+    resolution: {integrity: sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==}
+    engines: {node: '>= 0.8.15'}
+    dev: true
+
+  /rollup@3.26.3:
+    resolution: {integrity: sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==}
+    engines: {node: '>=14.18.0', npm: '>=8.0.0'}
+    hasBin: true
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /run-parallel@1.2.0:
+    resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+    dependencies:
+      queue-microtask: 1.2.3
+    dev: true
+
+  /safer-buffer@2.1.2:
+    resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+  /sax@1.2.4:
+    resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
+    dev: true
+    optional: true
+
+  /scroll-into-view-if-needed@2.2.31:
+    resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
+    dependencies:
+      compute-scroll-into-view: 1.0.20
+    dev: false
+
+  /scule@1.0.0:
+    resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==}
+    dev: true
+
+  /seemly@0.3.6:
+    resolution: {integrity: sha512-lEV5VB8BUKTo/AfktXJcy+JeXns26ylbMkIUco8CYREsQijuz4mrXres2Q+vMLdwkuLxJdIPQ8IlCIxLYm71Yw==}
+    dev: false
+
+  /semver@5.7.2:
+    resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
+    hasBin: true
+    dev: true
+    optional: true
+
+  /semver@6.3.1:
+    resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+    hasBin: true
+    dev: true
+
+  /sentence-case@3.0.4:
+    resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.6.0
+      upper-case-first: 2.0.2
+    dev: true
+
+  /side-channel@1.0.4:
+    resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+    dependencies:
+      call-bind: 1.0.2
+      get-intrinsic: 1.2.1
+      object-inspect: 1.12.3
+    dev: false
+
+  /simple-swizzle@0.2.2:
+    resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+    dependencies:
+      is-arrayish: 0.3.2
+    dev: false
+
+  /snake-case@3.0.4:
+    resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
+    dependencies:
+      dot-case: 3.0.4
+      tslib: 2.6.0
+    dev: true
+
+  /source-map-js@1.0.2:
+    resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+    engines: {node: '>=0.10.0'}
+
+  /source-map-support@0.5.21:
+    resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+    dependencies:
+      buffer-from: 1.1.2
+      source-map: 0.6.1
+    dev: true
+
+  /source-map@0.6.1:
+    resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+    engines: {node: '>=0.10.0'}
+
+  /sourcemap-codec@1.4.8:
+    resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
+    deprecated: Please use @jridgewell/sourcemap-codec instead
+
+  /split-on-first@3.0.0:
+    resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==}
+    engines: {node: '>=12'}
+    dev: false
+
+  /stackblur-canvas@2.6.0:
+    resolution: {integrity: sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg==}
+    engines: {node: '>=0.1.14'}
+    dev: true
+
+  /store@2.0.12:
+    resolution: {integrity: sha512-eO9xlzDpXLiMr9W1nQ3Nfp9EzZieIQc10zPPMP5jsVV7bLOziSFFBP0XoDXACEIFtdI+rIz0NwWVA/QVJ8zJtw==}
+    dev: false
+
+  /strip-literal@1.0.1:
+    resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==}
+    dependencies:
+      acorn: 8.10.0
+    dev: true
+
+  /supports-color@5.5.0:
+    resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+    engines: {node: '>=4'}
+    dependencies:
+      has-flag: 3.0.0
+    dev: true
+
+  /supports-preserve-symlinks-flag@1.0.0:
+    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /svg-pathdata@6.0.3:
+    resolution: {integrity: sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==}
+    engines: {node: '>=12.0.0'}
+    dev: true
+
+  /svg-tags@1.0.0:
+    resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
+    dev: true
+
+  /svgo@3.0.2:
+    resolution: {integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==}
+    engines: {node: '>=14.0.0'}
+    hasBin: true
+    dependencies:
+      '@trysound/sax': 0.2.0
+      commander: 7.2.0
+      css-select: 5.1.0
+      css-tree: 2.3.1
+      csso: 5.0.5
+      picocolors: 1.0.0
+    dev: true
+
+  /systemjs@6.14.1:
+    resolution: {integrity: sha512-8ftwWd+XnQtZ/aGbatrN4QFNGrKJzmbtixW+ODpci7pyoTajg4sonPP8aFLESAcuVxaC1FyDESt+SpfFCH9rZQ==}
+    dev: true
+
+  /terser@5.16.8:
+    resolution: {integrity: sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==}
+    engines: {node: '>=10'}
+    hasBin: true
+    dependencies:
+      '@jridgewell/source-map': 0.3.5
+      acorn: 8.10.0
+      commander: 2.20.3
+      source-map-support: 0.5.21
+    dev: true
+
+  /text-segmentation@1.0.3:
+    resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
+    dependencies:
+      utrie: 1.0.2
+    dev: false
+
+  /to-fast-properties@2.0.0:
+    resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+    engines: {node: '>=4'}
+
+  /to-regex-range@5.0.1:
+    resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+    engines: {node: '>=8.0'}
+    dependencies:
+      is-number: 7.0.0
+    dev: true
+
+  /tr46@0.0.3:
+    resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+    dev: true
+
+  /treemate@0.3.11:
+    resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==}
+    dev: false
+
+  /tslib@2.6.0:
+    resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==}
+    dev: true
+
+  /typescript@4.9.3:
+    resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
+    engines: {node: '>=4.2.0'}
+    hasBin: true
+    dev: true
+
+  /ufo@1.1.2:
+    resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==}
+    dev: true
+
+  /umi-request@1.4.0:
+    resolution: {integrity: sha512-OknwtQZddZHi0Ggi+Vr/olJ7HNMx4AzlywyK0W3NZBT7B0stjeZ9lcztA85dBgdAj3KVk8uPJPZSnGaDjELhrA==}
+    dependencies:
+      isomorphic-fetch: 2.2.1
+      qs: 6.11.2
+    dev: false
+
+  /unicode-canonical-property-names-ecmascript@2.0.0:
+    resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /unicode-match-property-ecmascript@2.0.0:
+    resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==}
+    engines: {node: '>=4'}
+    dependencies:
+      unicode-canonical-property-names-ecmascript: 2.0.0
+      unicode-property-aliases-ecmascript: 2.1.0
+    dev: true
+
+  /unicode-match-property-value-ecmascript@2.1.0:
+    resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /unicode-property-aliases-ecmascript@2.1.0:
+    resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /unimport@3.1.0:
+    resolution: {integrity: sha512-ybK3NVWh30MdiqSyqakrrQOeiXyu5507tDA0tUf7VJHrsq4DM6S43gR7oAsZaFojM32hzX982Lqw02D3yf2aiA==}
+    dependencies:
+      '@rollup/pluginutils': 5.0.2
+      escape-string-regexp: 5.0.0
+      fast-glob: 3.3.0
+      local-pkg: 0.4.3
+      magic-string: 0.30.1
+      mlly: 1.4.0
+      pathe: 1.1.1
+      pkg-types: 1.0.3
+      scule: 1.0.0
+      strip-literal: 1.0.1
+      unplugin: 1.4.0
+    transitivePeerDependencies:
+      - rollup
+    dev: true
+
+  /universal-user-agent@6.0.0:
+    resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==}
+    dev: true
+
+  /universalify@2.0.0:
+    resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
+    engines: {node: '>= 10.0.0'}
+    dev: true
+
+  /unplugin-auto-import@0.16.6:
+    resolution: {integrity: sha512-M+YIITkx3C/Hg38hp8HmswP5mShUUyJOzpifv7RTlAbeFlO2Tyw0pwrogSSxnipHDPTtI8VHFBpkYkNKzYSuyA==}
+    engines: {node: '>=14'}
+    peerDependencies:
+      '@nuxt/kit': ^3.2.2
+      '@vueuse/core': '*'
+    peerDependenciesMeta:
+      '@nuxt/kit':
+        optional: true
+      '@vueuse/core':
+        optional: true
+    dependencies:
+      '@antfu/utils': 0.7.5
+      '@rollup/pluginutils': 5.0.2
+      fast-glob: 3.3.0
+      local-pkg: 0.4.3
+      magic-string: 0.30.1
+      minimatch: 9.0.3
+      unimport: 3.1.0
+      unplugin: 1.4.0
+    transitivePeerDependencies:
+      - rollup
+    dev: true
+
+  /unplugin-vue-components@0.24.1(vue@3.2.47):
+    resolution: {integrity: sha512-T3A8HkZoIE1Cja95xNqolwza0yD5IVlgZZ1PVAGvVCx8xthmjsv38xWRCtHtwl+rvZyL9uif42SRkDGw9aCfMA==}
+    engines: {node: '>=14'}
+    peerDependencies:
+      '@babel/parser': ^7.15.8
+      '@nuxt/kit': ^3.2.2
+      vue: 2 || 3
+    peerDependenciesMeta:
+      '@babel/parser':
+        optional: true
+      '@nuxt/kit':
+        optional: true
+    dependencies:
+      '@antfu/utils': 0.7.5
+      '@rollup/pluginutils': 5.0.2
+      chokidar: 3.5.3
+      debug: 4.3.4
+      fast-glob: 3.3.0
+      local-pkg: 0.4.3
+      magic-string: 0.30.1
+      minimatch: 7.4.6
+      resolve: 1.22.2
+      unplugin: 1.4.0
+      vue: 3.2.47
+    transitivePeerDependencies:
+      - rollup
+      - supports-color
+    dev: true
+
+  /unplugin@1.4.0:
+    resolution: {integrity: sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==}
+    dependencies:
+      acorn: 8.10.0
+      chokidar: 3.5.3
+      webpack-sources: 3.2.3
+      webpack-virtual-modules: 0.5.0
+    dev: true
+
+  /update-browserslist-db@1.0.11(browserslist@4.21.9):
+    resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
+    hasBin: true
+    peerDependencies:
+      browserslist: '>= 4.21.0'
+    dependencies:
+      browserslist: 4.21.9
+      escalade: 3.1.1
+      picocolors: 1.0.0
+    dev: true
+
+  /upper-case-first@2.0.2:
+    resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==}
+    dependencies:
+      tslib: 2.6.0
+    dev: true
+
+  /upper-case@2.0.2:
+    resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==}
+    dependencies:
+      tslib: 2.6.0
+    dev: true
+
+  /url-polyfill@1.1.12:
+    resolution: {integrity: sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==}
+    dev: false
+
+  /utrie@1.0.2:
+    resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
+    dependencies:
+      base64-arraybuffer: 1.0.2
+    dev: false
+
+  /vant@4.1.2(vue@3.2.47):
+    resolution: {integrity: sha512-iRUYBR5zDbs7O0UTxauyW/0XbJoE0g/eHipn0y3QxXeazdmNiaV0kGbBKRJ8vE/7p74zila/O5LzDiYbPDDN7Q==}
+    peerDependencies:
+      vue: ^3.0.0
+    dependencies:
+      '@vant/popperjs': 1.3.0
+      '@vant/use': 1.5.1(vue@3.2.47)
+      vue: 3.2.47
+    dev: false
+
+  /vdirs@0.1.8(vue@3.2.47):
+    resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==}
+    peerDependencies:
+      vue: ^3.0.11
+    dependencies:
+      evtd: 0.2.4
+      vue: 3.2.47
+    dev: false
+
+  /vfonts@0.0.3:
+    resolution: {integrity: sha512-nguyw8L6Un8eelg1vQ31vIU2ESxqid7EYmy8V+MDeMaHBqaRSkg3dTBToC1PR00D89UzS/SLkfYPnx0Wf23IQQ==}
+    dev: false
+
+  /vite-plugin-mkcert@1.15.0(vite@4.2.0):
+    resolution: {integrity: sha512-0Pz7iExvo7pS2HsxMe6Y/HIrsFJidXN8Sju7tsL1XYQdbUKb/D0L5Wkj3UoGQmbbWZUFf8nHHa0XYbd4FH6ZrA==}
+    engines: {node: '>=v16.7.0'}
+    peerDependencies:
+      vite: '>=3'
+    dependencies:
+      '@octokit/rest': 19.0.13
+      axios: 1.4.0(debug@4.3.4)
+      debug: 4.3.4
+      picocolors: 1.0.0
+      vite: 4.2.0(@types/node@18.15.11)(less@4.1.3)(terser@5.16.8)
+    transitivePeerDependencies:
+      - encoding
+      - supports-color
+    dev: true
+
+  /vite-plugin-style-import@2.0.0(vite@4.2.0):
+    resolution: {integrity: sha512-qtoHQae5dSUQPo/rYz/8p190VU5y19rtBaeV7ryLa/AYAU/e9CG89NrN/3+k7MR8mJy/GPIu91iJ3zk9foUOSA==}
+    peerDependencies:
+      vite: '>=2.0.0'
+    dependencies:
+      '@rollup/pluginutils': 4.2.1
+      change-case: 4.1.2
+      console: 0.7.2
+      es-module-lexer: 0.9.3
+      fs-extra: 10.1.0
+      magic-string: 0.25.9
+      pathe: 0.2.0
+      vite: 4.2.0(@types/node@18.15.11)(less@4.1.3)(terser@5.16.8)
+    dev: true
+
+  /vite-svg-loader@4.0.0:
+    resolution: {integrity: sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==}
+    dependencies:
+      '@vue/compiler-sfc': 3.3.4
+      svgo: 3.0.2
+    dev: true
+
+  /vite@4.2.0(@types/node@18.15.11)(less@4.1.3)(terser@5.16.8):
+    resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    hasBin: true
+    peerDependencies:
+      '@types/node': '>= 14'
+      less: '*'
+      sass: '*'
+      stylus: '*'
+      sugarss: '*'
+      terser: ^5.4.0
+    peerDependenciesMeta:
+      '@types/node':
+        optional: true
+      less:
+        optional: true
+      sass:
+        optional: true
+      stylus:
+        optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+    dependencies:
+      '@types/node': 18.15.11
+      esbuild: 0.17.19
+      less: 4.1.3
+      postcss: 8.4.26
+      resolve: 1.22.2
+      rollup: 3.26.3
+      terser: 5.16.8
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /vooks@0.2.12(vue@3.2.47):
+    resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==}
+    peerDependencies:
+      vue: ^3.0.0
+    dependencies:
+      evtd: 0.2.4
+      vue: 3.2.47
+    dev: false
+
+  /vue-router@4.1.6(vue@3.2.47):
+    resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      '@vue/devtools-api': 6.5.0
+      vue: 3.2.47
+    dev: false
+
+  /vue-template-compiler@2.7.14:
+    resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
+    dependencies:
+      de-indent: 1.0.2
+      he: 1.2.0
+    dev: true
+
+  /vue-tsc@1.2.0(typescript@4.9.3):
+    resolution: {integrity: sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==}
+    hasBin: true
+    peerDependencies:
+      typescript: '*'
+    dependencies:
+      '@volar/vue-language-core': 1.2.0
+      '@volar/vue-typescript': 1.2.0
+      typescript: 4.9.3
+    dev: true
+
+  /vue3-lottie@2.5.0(vue@3.2.47):
+    resolution: {integrity: sha512-JwlTzykr4ofPnSXsTAPt571RDrtQNy66H8w/zYBVHNgrCRG4RINI30c/oJx3Dj+XpxuktpKzgfI08tv1FjYkAQ==}
+    engines: {node: '>=12'}
+    peerDependencies:
+      vue: ^3.2
+    dependencies:
+      lodash-es: 4.17.21
+      lottie-web: 5.12.2
+      vue: 3.2.47
+    dev: false
+
+  /vue@3.2.47:
+    resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==}
+    dependencies:
+      '@vue/compiler-dom': 3.2.47
+      '@vue/compiler-sfc': 3.2.47
+      '@vue/runtime-dom': 3.2.47
+      '@vue/server-renderer': 3.2.47(vue@3.2.47)
+      '@vue/shared': 3.2.47
+
+  /vueuc@0.4.51(vue@3.2.47):
+    resolution: {integrity: sha512-pLiMChM4f+W8czlIClGvGBYo656lc2Y0/mXFSCydcSmnCR1izlKPGMgiYBGjbY9FDkFG8a2HEVz7t0DNzBWbDw==}
+    peerDependencies:
+      vue: ^3.0.11
+    dependencies:
+      '@css-render/vue3-ssr': 0.15.12(vue@3.2.47)
+      '@juggle/resize-observer': 3.4.0
+      css-render: 0.15.12
+      evtd: 0.2.4
+      seemly: 0.3.6
+      vdirs: 0.1.8(vue@3.2.47)
+      vooks: 0.2.12(vue@3.2.47)
+      vue: 3.2.47
+    dev: false
+
+  /webidl-conversions@3.0.1:
+    resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+    dev: true
+
+  /webpack-sources@3.2.3:
+    resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
+    engines: {node: '>=10.13.0'}
+    dev: true
+
+  /webpack-virtual-modules@0.5.0:
+    resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
+    dev: true
+
+  /whatwg-fetch@3.6.2:
+    resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==}
+    dev: false
+
+  /whatwg-url@5.0.0:
+    resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
+    dependencies:
+      tr46: 0.0.3
+      webidl-conversions: 3.0.1
+    dev: true
+
+  /wrappy@1.0.2:
+    resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+    dev: true
+
+  /ws@8.13.0:
+    resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==}
+    engines: {node: '>=10.0.0'}
+    peerDependencies:
+      bufferutil: ^4.0.1
+      utf-8-validate: '>=5.0.2'
+    peerDependenciesMeta:
+      bufferutil:
+        optional: true
+      utf-8-validate:
+        optional: true
+    dev: false
+
+  /yallist@3.1.1:
+    resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+    dev: true

Різницю між файлами не показано, бо вона завелика
+ 107 - 0
public/abc2svg/abc2svg-1.js


+ 366 - 0
public/abc2svg/abcweb-1.js

@@ -0,0 +1,366 @@
+// abc2svg - ABC to SVG translator
+// @source: https://chiselapp.com/user/moinejf/repository/abc2svg
+// Copyright (C) 2014-2023 Jean-Francois Moine - LGPL3+
+//abcweb-1.js file to include in html pages
+window.onerror = function (msg, url, line) {
+    if (typeof msg == 'string')
+        alert("window error: " + msg + "\nURL: " + url + "\nLine: " + line)
+    else if (typeof msg == 'object')
+        alert("window error: " + msg.type + ' ' + msg.target.src)
+    else
+        alert("window error: " + msg)
+    return false
+}
+var user, abcplay
+if (typeof abc2svg == "undefined")
+    var abc2svg = {}
+abc2svg.mu = ""
+abc2svg.abc_end = function () { }
+abc2svg.jsdir = document.currentScript ? document.currentScript.src.match(/.*\//) : (function () {
+    var s_a = document.getElementsByTagName('script')
+    for (var k = 0; k < s_a.length; k++) {
+        if (s_a[k].src.indexOf("abcweb") >= 0)
+            return s_a[k].src.match(/.*\//) || ''
+    }
+    return ""
+})()
+abc2svg.loadjs = function (fn, relay, onerror) {
+    var s = document.createElement('script')
+    if (/:\/\//.test(fn))
+        s.src = fn
+    else
+        s.src = abc2svg.jsdir + fn
+    s.onload = relay
+    s.onerror = function () {
+        if (onerror)
+            onerror(fn)
+        else
+            alert('error loading ' + fn)
+    }
+    document.head.appendChild(s)
+}
+function dom_loaded() {
+    var abc, src, outb, err, a_inc = {}, tune_lst = [], html, busy, playing, playconf = { onend: function () { playing = 0 } }
+    function visible() {
+        var mu, r, wh = window.innerHeight || document.documentElement.clientHeight
+        while (1) {
+            mu = abc2svg.alldiv[0]
+            if (!mu)
+                break
+            r = mu.d.getBoundingClientRect()
+            if (r.top > wh)
+                break
+            musgen(mu)
+            abc2svg.alldiv.shift()
+        }
+        if (abc2svg.alldiv.length) {
+            if (!abc2svg.onscroll) {
+                abc2svg.onscroll = visible
+                window.addEventListener("scroll", visible)
+            }
+        } else { window.removeEventListener("scroll", visible) }
+    }
+    function get_p(e) {
+        var i, j, k, r, o = '', sh = document.styleSheets, s = e.style
+        c = e.getAttribute("class")
+        if (c) {
+            c = '.' + c
+            for (i = 0; i < sh.length; i++) {
+                r = sh[i].rules
+                for (j = 0; j < r.length; j++) {
+                    if (r[j].selectorText == c)
+                        break
+                }
+                if (j < r.length)
+                    break
+            }
+            if (i < sh.length) {
+                r = r[j]
+                for (i = 0; i < r.style.length; i++) {
+                    k = r.style[i]
+                    if (k[0] == '-' && k[1] == '-')
+                        o += '%%' + k.slice(2) + ' '
+                            + r.style.getPropertyValue(k)
+                            + '\n'
+                }
+            }
+        }
+        for (i = 0; i < s.length; i++) {
+            k = s[i]
+            if (k[0] == '-' && k[1] == '-')
+                o += '%%' + k.slice(2) + ' '
+                    + s.getPropertyValue(k)
+                    + '\n'
+        }
+        return o
+    }
+    function move_music(src) {
+        var re, res, i, j, k, t, re_stop = /\n<|\n%.begin[^\s]+/g, ss = 0, out = ""
+        if (/<[^>]* class="[^"]*abc[^"]*/.test(src))
+            re = '<[^>]* class="[^"]*abc[^"]*'
+        else
+            re = '%abc-\\d|X:\\s*\\d'
+        re = new RegExp('(^|\n)(' + re + ')', 'g')
+        while (1) {
+            res = re.exec(src)
+            if (!res)
+                break
+            i = re.lastIndex - res[0].length
+            if (i > ss) {
+                out += src.slice(ss, i)
+                html = 1
+            }
+            t = res[2]
+            if (t[0] == '<') {
+                i = src.indexOf('>', i) + 1
+                j = res[2].indexOf(' ')
+                t = res[2].slice(1, j)
+                j = src.indexOf('</' + t + '>', i)
+                ss = j + t.length + 4
+            } else {
+                re_stop.lastIndex = i
+                while (1) {
+                    res = re_stop.exec(src)
+                    if (!res || res[0] == "\n<")
+                        break
+                    k = src.indexOf(res[0].replace("begin", "end"), re_stop.lastIndex)
+                    if (k < 0)
+                        break
+                    re_stop.lastIndex = k
+                }
+                if (!res || k < 0)
+                    j = src.length
+                else
+                    j = re_stop.lastIndex - 1
+                ss = j
+            }
+            out += '<script type="text/vnd.abc">\n'
+                + src.slice(i, j)
+                + '</script>\n'
+            re.lastIndex = ss
+        }
+        out += src.slice(ss)
+        if (abc2svg.page && html)
+            out += '\
+<pre class="nop" style="background:#ff8080">\
+Printing may be bad because the file contains pure HTML and %%pageheight\
+</pre>\n'
+        document.body.innerHTML = out
+    }
+    function save_music() {
+        var i, k, div, c, s, sa
+        abc2svg.music = [{ t: "", n: "mus0" }]
+        k = location.search
+        if (k) {
+            k = k.substr(1).split("&")
+            for (i = 0; i < k.length; i++)
+                abc2svg.music[0].t += "%%"
+                    + decodeURIComponent(k[i].replace('=', ' '))
+                    + '\n'
+        }
+        while (1) {
+            sa = document.getElementsByTagName('script')
+            for (i = 0; i < sa.length; i++) {
+                s = sa[i]
+                if (s.type == 'text/vnd.abc')
+                    break
+            }
+            if (i >= sa.length)
+                break
+            c = get_p(s)
+            div = document.createElement('div')
+            if (s.text.indexOf('\nX:') < 0) {
+                abc2svg.music[0].t += c + s.innerHTML
+                if (!abc2svg.music[0].d)
+                    abc2svg.music[0].d = div
+            } else { abc2svg.music.push({ n: "mus" + abc2svg.music.length, t: c + s.innerHTML, d: div }) }
+            s.parentNode.replaceChild(div, s)
+        }
+    }
+    function musgen(mu) {
+        var t = mu.t
+        if (busy) {
+            mu.w = 1
+            return
+        }
+        busy = 1
+        function render() {
+            var i, j, e
+            outb = err = ""
+            abc.tosvg(mu.n, t)
+            abc2svg.abc_end()
+            if (mu.d) {
+                if (err)
+                    outb += '<pre class="nop" style="background:#ff8080">'
+                        + err + "</pre>\n"
+                if (abc.cfmt().with_source && outb)
+                    outb = '<pre class="source">'
+                        + clean_txt(t)
+                        + '</pre>\n\
+<div class="source">\n'
+                        + outb
+                        + '</div>\n'
+                mu.d.innerHTML = outb
+                mu.d.addEventListener('click', abc2svg.playseq)
+                e = mu.d.getElementsByTagName('svg')
+                for (i = 0; i < e.length; i++) {
+                    j = e[i].getAttribute('class')
+                    if (!j)
+                        continue
+                    j = j.match(/tune(\d+)/)
+                    if (!j)
+                        continue
+                    j = j[1]
+                    tune_lst[j] = null
+                }
+            }
+            mu.w = busy = 0
+            for (i = 1; i < abc2svg.music.length; i++) {
+                if (abc2svg.music[i].w) {
+                    musgen(abc2svg.music[i])
+                    break
+                }
+            }
+        }
+        function include() {
+            var i, j, fn, r, k = 0
+            while (1) {
+                i = t.indexOf('%%abc-include ', k)
+                if (i < 0) {
+                    render()
+                    return
+                }
+                i += 14
+                j = t.indexOf('\n', i)
+                fn = t.slice(i, j).trim()
+                if (!a_inc[fn])
+                    break
+                k = j
+            }
+            r = new XMLHttpRequest()
+            r.open('GET', fn, true)
+            r.onload = function () {
+                if (r.status === 200) {
+                    a_inc[fn] = r.responseText
+                    if (abc2svg.modules.load(a_inc[fn], include))
+                        include()
+                } else {
+                    a_inc[fn] = '%\n'
+                    alert('Error getting ' + fn + '\n' + r.statusText)
+                    include()
+                }
+            }
+            r.onerror = function () {
+                a_inc[fn] = '%\n'
+                alert('Error getting ' + fn + '\n' + r.statusText)
+                include()
+            }
+            r.send()
+        }
+        if (abc2svg.modules.load(t, include))
+            include()
+    }
+    abc2svg.musgen = musgen
+    user = { read_file: function (fn) { return a_inc[fn] }, errmsg: function (msg, l, c) { err += clean_txt(msg) + '\n' }, img_out: function (p) { outb += p } }
+    function clean_txt(txt) {
+        return txt.replace(/<|>|&.*?;|&/g, function (c) {
+            switch (c) {
+                case '<': return "&lt;"
+                case '>': return "&gt;"
+                case '&': return "&amp;"
+            }
+            return c
+        })
+    }
+    abc2svg.playseq = function (evt) {
+        if (playing) {
+            abcplay.stop()
+            return
+        }
+        var i, j, svg = evt.target, e = svg
+        while (svg.tagName != 'svg') {
+            svg = svg.parentNode
+            if (!svg)
+                return
+        }
+        i = svg.getAttribute('class')
+        if (!i)
+            return
+        i = i.match(/tune(\d+)/)
+        if (!i)
+            return
+        i = i[1]
+        if (!abcplay) {
+            if (typeof AbcPlay == "undefined") {
+                abc2svg.playseq = function () { }
+                return
+            }
+            if (abc.cfmt().soundfont)
+                playconf.sfu = abc.cfmt().soundfont
+            abcplay = AbcPlay(playconf)
+        }
+        if (!tune_lst[i]) {
+            tune_lst[i] = abc.tunes[i]
+            abcplay.add(tune_lst[i][0], tune_lst[i][1], tune_lst[i][3])
+        }
+        s = tune_lst[i][0]
+        i = e.getAttribute('class')
+        if (i)
+            i = i.match(/abcr _(\d+)_/)
+        if (i) {
+            i = i[1]
+            while (s && s.istart != i)
+                s = s.ts_next
+            if (!s) {
+                alert("play bug: no such symbol in the tune")
+                return
+            }
+        }
+        while (s && !s.fname)
+            s = s.ts_next
+        for (i = 1; i < abc2svg.music.length; i++) {
+            if (abc2svg.music[i].n == s.fname)
+                break
+        }
+        abc2svg.mu = abc2svg.music[i]
+        playing = 1
+        abcplay.play(s, null)
+    }
+    src = document.body.innerHTML
+    if (!abc2svg.Abc) {
+        abc2svg.loadjs("abc2svg-1.js", dom_loaded)
+        return
+    }
+    if (src.indexOf('type="text/vnd.abc"') < 0)
+        move_music(src)
+    save_music()
+    abc = new abc2svg.Abc(user)
+    if (typeof follow == "function")
+        follow(abc, user, playconf)
+    if (abc2svg.music[0].t)
+        musgen(abc2svg.music[0])
+    abc2svg.alldiv = []
+    for (var i = 1; i < abc2svg.music.length; i++)
+        abc2svg.alldiv.push(abc2svg.music[i])
+    visible()
+}
+abc2svg.get_music = function (d) {
+    var i, mu
+    for (var i = 1; i < abc2svg.music.length; i++) {
+        mu = abc2svg.music[i]
+        if (mu.d == d)
+            return mu.t
+    }
+}
+abc2svg.set_music = function (d, t) {
+    var i, mu
+    for (var i = 1; i < abc2svg.music.length; i++) {
+        mu = abc2svg.music[i]
+        if (mu.d == d) {
+            mu.t = t
+            abc2svg.musgen(mu)
+            break
+        }
+    }
+}
+window.addEventListener("load", dom_loaded, { once: true })

Різницю між файлами не показано, бо вона завелика
+ 1 - 0
public/abc2svg/jquery-1.11.1.min.js


+ 820 - 0
public/abc2svg/snd-1.js

@@ -0,0 +1,820 @@
+// abc2svg - ABC to SVG translator
+// @source: https://chiselapp.com/user/moinejf/repository/abc2svg
+// Copyright (C) 2014-2023 Jean-Francois Moine - LGPL3+
+//snd-1.js-file to include in html pages with abc2svg-1.js for playing
+function AbcPlay(i_conf){var conf=i_conf,init={},audio=ToAudio(),audio5,midi5,current,abcplay={clear:audio.clear,add:audio.add,set_sfu:function(v){if(v==undefined)
+return conf.sfu
+conf.sfu=v},set_speed:function(v){if(v==undefined)
+return conf.speed
+conf.new_speed=v},set_vol:function(v){if(v==undefined)
+return conf.gain;conf.gain=v
+if(current&&current.set_vol)
+current.set_vol(v)},play:play,stop:vf}
+function vf(){}
+function play(istart,i_iend,a_e){init.istart=istart;init.i_iend=i_iend;init.a_e=a_e
+if(midi5)
+midi5.get_outputs(play2)
+else
+play2()}
+function play2(out){var o
+if(!out)
+out=[]
+o=audio5.get_outputs()
+if(o)
+Array.prototype.push.apply(out,o)
+if(out.length==0){if(conf.onend)
+conf.onend()
+return}
+if(out.length==1){o=0}else{o=-1
+var pr="Use"
+for(var i=0;i<out.length;i++)
+pr+="\n "+i+": "+out[i]
+var res=window.prompt(pr,'0')
+if(res){o=Number(res)
+if(isNaN(o)||o<0||o>=out.length)
+o=-1}
+if(!res||o<0){if(conf.onend)
+conf.onend()
+return}}
+current=out[o]=='sf2'?audio5:midi5;abcplay.play=current.play;abcplay.stop=current.stop
+if(current.set_output)
+current.set_output(out[o]);abcplay.play(init.istart,init.i_iend,init.a_e)}
+conf.gain=0.7;conf.speed=1;(function(){var v
+try{if(!localStorage)
+return}catch(e){return}
+if(!conf.sfu){v=localStorage.getItem("sfu")
+if(v)
+conf.sfu=v}
+v=localStorage.getItem("volume")
+if(v)
+conf.gain=Number(v)})()
+if(typeof Midi5=="function")
+midi5=Midi5(conf)
+if(typeof Audio5=="function")
+audio5=Audio5(conf);return abcplay}
+if(typeof module=='object'&&typeof exports=='object')
+exports.AbcPlay=AbcPlay
+if(!abc2svg)
+var abc2svg={}
+function ToAudio(){return{add:function(first,voice_tb,cfmt){var toaud=this,C=abc2svg.C,p_time=0,abc_time=0,play_fac=C.BLEN/4*120/60,i,n,dt,d,v,s=first,rst=s,rst_fac,rsk=[],b_tim,b_typ
+function get_beat(){var s=first.p_v.meter
+if(!s.a_meter[0])
+return C.BLEN/4
+if(!s.a_meter[0].bot)
+return(s.a_meter[1]&&s.a_meter[1].top=='|')?C.BLEN/2:C.BLEN/4
+if(s.a_meter[0].bot=="8"&&s.a_meter[0].top%3==0)
+return C.BLEN/8*3
+return C.BLEN/s.a_meter[0].bot|0}
+function def_beats(){var i,s2,s3,tim,last_d,beat=get_beat(),d=first.p_v.meter.wmeasure,nb=d/beat|0,v=voice_tb.length,p_v={id:"_beats",v:v,sym:{type:C.BLOCK,v:v,subtype:"midiprog",chn:9,instr:16384,ts_prev:first}},s={type:C.NOTE,v:v,p_v:p_v,dur:beat,nhd:0,notes:[{midi:37}]}
+for(s2=first;s2;s2=s2.ts_next){if(s2.bar_type&&s2.time){nb=(2*d-s2.time)/beat|0
+last_d=beat-s2.time
+break}}
+s2=p_v.sym
+for(s3=first;s3&&!s3.time;s3=s3.ts_next){if(s3.type==C.TEMPO){s3=Object.create(s3)
+s3.v=v
+s3.p_v=p_v
+s3.prev=s3.ts_prev=s2
+s2.next=s2.ts_next=s3
+s2=s3
+play_fac=set_tempo(s2)
+break}}
+voice_tb[v]=p_v
+p_v.sym.p_v=p_v
+tim=abc_time=-d
+first.time=s2.time=tim
+if(s3)
+p_v.sym.time=tim
+for(i=0;i<nb;i++){s3=Object.create(s)
+s3.time=tim
+s3.prev=s2
+s2.next=s3
+s3.ts_prev=s2
+s2.ts_next=s3
+s2=s3
+if(last_d&&i==nb-1){s3.dur=s3.dur_orig=s3.notes[0].dur=last_d}
+tim+=beat}
+s2.ts_next=first.ts_next
+s2.ts_next.ts_prev=s2
+first.ts_next=p_v.sym}
+function build_parts(first){var i,j,c,n,v,s=first,p=s.parts,st=[],r=""
+for(i=0;i<p.length;i++){c=p[i]
+switch(c){case'.':continue
+case'(':st.push(r.length)
+continue
+case')':j=st.pop()
+if(j==undefined)
+j=r.length
+continue}
+if(c>='A'&&c<='Z'){j=r.length
+r+=c
+continue}
+n=Number(c)
+if(isNaN(n))
+break
+v=r.slice(j)
+if(r.length+v.length*n>128)
+continue
+while(--n>0)
+r+=v}
+s.parts=r
+s.p_s=[]
+while(1){if(!s.ts_next){s.part1=first
+break}
+s=s.ts_next
+if(s.part){s.part1=first
+v=s.part.text[0]
+for(i=0;i<first.parts.length;i++){if(first.parts[i]==v)
+first.p_s[i]=s}}}}
+function gen_grace(s){var g,i,n,t,d,s2,next=s.next
+if(s.sappo){d=C.BLEN/16}else if((!next||next.type!=C.NOTE)&&s.prev&&s.prev.type==C.NOTE){d=s.prev.dur/2}else{d=next.dur/12
+if(!(d&(d-1)))
+d=next.dur/2
+else
+d=next.dur/3
+if(s.p_v.key.k_bagpipe)
+d/=2
+next.time+=d
+next.dur-=d}
+n=0
+for(g=s.extra;g;g=g.next)
+n++
+d/=n*play_fac
+t=p_time
+for(g=s.extra;g;g=g.next){g.ptim=t
+g.pdur=d
+t+=d}}
+function set_tempo(s){var i,d=0,n=s.tempo_notes.length
+for(i=0;i<n;i++)
+d+=s.tempo_notes[i]
+return d*s.tempo/60}
+function set_variant(s){var d,n=s.text.match(/[1-8]-[2-9]|[1-9,.]|[^\s]+$/g)
+while(1){d=n.shift()
+if(!d)
+break
+if(d[1]=='-')
+for(i=d[0];i<=d[2];i++)
+rsk[i]=s
+else if(d>='1'&&d<='9')
+rsk[Number(d)]=s
+else if(d!=',')
+rsk.push(s)}}
+if(cfmt.chord)
+abc2svg.chord(first,voice_tb,cfmt)
+if(cfmt.playbeats)
+def_beats()
+if(s.parts)
+build_parts(s)
+rst_fac=play_fac
+while(s){if(s.noplay){s=s.ts_next
+continue}
+dt=s.time-abc_time
+if(dt!=0){p_time+=dt/play_fac
+abc_time=s.time}
+s.ptim=p_time
+if(s.part){rst=s
+rst_fac=play_fac}
+switch(s.type){case C.BAR:if(s.time!=b_tim){b_tim=s.time
+b_typ=0}
+if(s.text&&rsk.length>1&&s.text[0]!='1'){if(b_typ&1)
+break
+b_typ|=1
+set_variant(s)
+play_fac=rst_fac
+rst=rsk[0]}
+if(s.bar_type[0]==':'){if(b_typ&2)
+break
+b_typ|=2
+s.rep_p=rst
+if(rst==rsk[0])
+s.rep_v=rsk}
+if(s.text){if(s.text[0]=='1'){if(b_typ&1)
+break
+b_typ|=1
+s.rep_s=rsk=[rst]
+if(rst.bar_type&&rst.bar_type.slice(-1)!=':')
+rst.bar_type+=':'
+set_variant(s)
+rst_fac=play_fac}}else if(s.bar_type.slice(-1)==':'){if(b_typ&4)
+break
+b_typ|=4
+rst=s
+rst_fac=play_fac}else if(s.rbstop==2){if(b_typ&8)
+break
+b_typ|=8
+rst=s
+rst_fac=play_fac}
+break
+case C.GRACE:if(s.time==0&&abc_time==0){dt=0
+if(s.sappo)
+dt=C.BLEN/16
+else if(!s.next||s.next.type!=C.NOTE)
+dt=d/2
+abc_time-=dt}
+gen_grace(s)
+break
+case C.REST:case C.NOTE:d=s.dur
+if(s.next&&s.next.type==C.GRACE){dt=0
+if(s.next.sappo)
+dt=C.BLEN/16
+else if(!s.next.next||s.next.next.type!=C.NOTE)
+dt=d/2
+s.next.time-=dt
+d-=dt}
+d/=play_fac
+s.pdur=d
+v=s.v
+break
+case C.TEMPO:if(s.tempo)
+play_fac=set_tempo(s)
+break}
+s=s.ts_next}}}}
+abc2svg.play_next=function(po){function do_tie(not_s,d){var i,s=not_s.s,C=abc2svg.C,v=s.v,end_time=s.time+s.dur,repv=po.repv
+while(1){s=s.ts_next
+if(!s||s.time>end_time)
+break
+if(s.type==C.BAR){if(s.rep_p){if(!po.repn){s=s.rep_p
+end_time=s.time}}
+if(s.rep_s){if(!s.rep_s[repv])
+break
+s=s.rep_s[repv++]
+end_time=s.time}
+while(s.ts_next&&!s.ts_next.dur)
+s=s.ts_next
+continue}
+if(s.time<end_time||!s.ti2)
+continue
+i=s.notes.length
+while(--i>=0){note=s.notes[i]
+if(note.tie_s==not_s){d+=s.pdur/po.conf.speed
+return note.tie_e?do_tie(note,d):d}}}
+return d}
+function set_ctrl(po,s2,t){var i,p_v=s2.p_v,s={subtype:"midictl",p_v:p_v,v:s2.v}
+for(i in p_v.midictl){s.ctrl=Number(i)
+s.val=p_v.midictl[i]
+po.midi_ctrl(po,s,t)}
+for(s=p_v.sym;s!=s2;s=s.next){if(s.subtype=="midictl")
+po.midi_ctrl(po,s,t)
+else if(s.subtype=='midiprog')
+po.midi_prog(po,s)}
+i=po.v_c[s2.v]
+if(i==undefined)
+po.v_c[s2.v]=i=s2.v<9?s2.v:s2.v+1
+if(po.c_i[i]==undefined)
+po.c_i[i]=0
+po.p_v[s2.v]=true}
+function play_cont(po){var d,i,st,m,note,g,s2,t,maxt,now,C=abc2svg.C,s=po.s_cur
+function var_end(s){var i,s2,s3,a=s.rep_v||s.rep_s
+ti=0
+for(i=1;i<a.length;i++){s2=a[i]
+if(s2.time>ti){ti=s2.time
+s3=s2}}
+for(s=s3;s!=po.s_end;s=s.ts_next){if(s.time==ti)
+continue
+if(s.rbstop==2)
+break}
+po.repv=1
+return s}
+if(po.stop){if(po.onend)
+po.onend(po.repv)
+return}
+while(s.noplay){s=s.ts_next
+if(!s||s==po.s_end){if(po.onend)
+po.onend(po.repv)
+return}}
+t=po.stim+s.ptim/po.conf.speed
+now=po.get_time(po)
+if(po.conf.new_speed){po.stim=now-(now-po.stim)*po.conf.speed/po.conf.new_speed
+po.conf.speed=po.conf.new_speed
+po.conf.new_speed=0
+t=po.stim+s.ptim/po.conf.speed}
+maxt=t+po.tgen
+po.timouts=[]
+while(1){if(!po.p_v[s.v])
+set_ctrl(po,s,t)
+switch(s.type){case C.BAR:s2=null
+if(s.rep_p){po.repv++
+if(!po.repn&&(!s.rep_v||po.repv<=s.rep_v.length)){s2=s.rep_p
+po.repn=true}else{if(s.rep_v)
+s2=var_end(s)
+po.repn=false}}
+if(s.rep_s){s2=s.rep_s[po.repv]
+if(s2){po.repn=false
+if(s2==s)
+s2=null}else{s2=var_end(s)
+if(s2==po.s_end)
+break}}
+if(s.bar_type.slice(-1)==':'&&s.bar_type[0]!=':')
+po.repv=1
+if(s2){po.stim+=(s.ptim-s2.ptim)/po.conf.speed
+s=s2
+while(s&&!s.dur)
+s=s.ts_next
+if(!s)
+break
+t=po.stim+s.ptim/po.conf.speed
+break}
+if(!s.part1){while(s.ts_next&&!s.ts_next.seqst){s=s.ts_next
+if(s.part1)
+break}
+if(!s.part1)
+break}
+default:if(s.part1&&po.i_p!=undefined){s2=s.part1.p_s[++po.i_p]
+if(s2){po.stim+=(s.ptim-s2.ptim)/po.conf.speed
+s=s2
+t=po.stim+s.ptim/po.conf.speed}else{s=po.s_end}
+po.repv=1}
+break}
+if(s&&s!=po.s_end){switch(s.type){case C.BAR:break
+case C.BLOCK:if(s.subtype=="midictl")
+po.midi_ctrl(po,s,t)
+else if(s.subtype=='midiprog')
+po.midi_prog(po,s)
+break
+case C.GRACE:for(g=s.extra;g;g=g.next){d=g.pdur/po.conf.speed
+for(m=0;m<=g.nhd;m++){note=g.notes[m]
+if(!note.noplay)
+po.note_run(po,g,note.midi,t+g.ptim-s.ptim,d)}}
+break
+case C.NOTE:case C.REST:d=s.pdur/po.conf.speed
+if(s.type==C.NOTE){for(m=0;m<=s.nhd;m++){note=s.notes[m]
+if(note.tie_s||note.noplay)
+continue
+po.note_run(po,s,note.midi,t,note.tie_e?do_tie(note,d):d)}}
+if(po.onnote&&s.istart){i=s.istart
+st=(t-now)*1000
+po.timouts.push(setTimeout(po.onnote,st,i,true))
+if(d>2)
+d-=.1
+setTimeout(po.onnote,st+d*1000,i,false)}
+break}}
+while(1){if(!s||s==po.s_end||!s.ts_next){if(po.onend)
+setTimeout(po.onend,(t-now+d)*1000,po.repv)
+po.s_cur=s
+return}
+s=s.ts_next
+if(!s.noplay)
+break}
+t=po.stim+s.ptim/po.conf.speed
+if(t>maxt)
+break}
+po.s_cur=s
+po.timouts.push(setTimeout(play_cont,(t-now)*1000
+-300,po))}
+function get_part(po){var s,i,s_p
+for(s=po.s_cur;s;s=s.ts_prev){if(s.parts){po.i_p=-1
+return}
+s_p=s.part1
+if(!s_p||!s_p.p_s)
+continue
+for(i=0;i<s_p.p_s.length;i++){if(s_p.p_s[i]==s){po.i_p=i
+return}}}}
+get_part(po)
+po.stim=po.get_time(po)+.3
+-po.s_cur.ptim*po.conf.speed
+po.p_v=[]
+if(!po.repv)
+po.repv=1
+play_cont(po)}
+if(typeof module=='object'&&typeof exports=='object')
+exports.ToAudio=ToAudio
+var abcsf2=[]
+function Audio5(i_conf){var po,conf=i_conf,empty=function(){},errmsg,ac,gain,model,parser,presets,instr=[],params=[],rates=[],w_instr=0
+var b64d=[]
+function init_b64d(){var b64l='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',l=b64l.length
+for(var i=0;i<l;i++)
+b64d[b64l[i]]=i
+b64d['=']=0}
+function b64dcod(s){var i,t,dl,a,l=s.length,j=0
+dl=l*3/4
+if(s[l-1]=='='){if(s[l-2]=='=')
+dl--
+dl--
+l-=4}
+a=new Uint8Array(dl)
+for(i=0;i<l;i+=4){t=(b64d[s[i]]<<18)+
+(b64d[s[i+1]]<<12)+
+(b64d[s[i+2]]<<6)+
+b64d[s[i+3]]
+a[j++]=(t>>16)&0xff
+a[j++]=(t>>8)&0xff
+a[j++]=t&0xff}
+if(l!=s.length){t=(b64d[s[i]]<<18)+
+(b64d[s[i+1]]<<12)+
+(b64d[s[i+2]]<<6)+
+b64d[s[i+3]]
+a[j++]=(t>>16)&0xff
+if(j<dl)
+a[j++]=(t>>8)&0xff}
+return a}
+function sample_cp(b,s){var i,n,a=b.getChannelData(0)
+for(i=0;i<s.length;i++)
+a[i]=s[i]/196608}
+function sf2_create(instr,sf2par,sf2pre){function get_instr(i){var instrument=sf2par.instrument,zone=sf2par.instrumentZone,j=instrument[i].instrumentBagIndex,jl=instrument[i+1]?instrument[i+1].instrumentBagIndex:zone.length,info=[]
+while(j<jl){instrumentGenerator=sf2par.createInstrumentGenerator_(zone,j)
+info.push({generator:instrumentGenerator.generator,})
+j++}
+return{info:info}}
+var i,j,k,sid,gen,parm,gparm,sample,infos,sampleRate,scale,b=instr>>7,p=instr%128,pr=sf2pre
+rates[instr]=[]
+for(i=0;i<pr.length;i++){gen=pr[i].header
+if(gen.preset==p&&gen.bank==b)
+break}
+pr=pr[i]
+if(!pr){errmsg('unknown instrument '+b+':'+p)
+return}
+pr=pr.info
+for(k=0;k<pr.length;k++){if(!pr[k].generator.instrument)
+continue
+gparm=null
+infos=get_instr(pr[k].generator.instrument.amount).info
+for(i=0;i<infos.length;i++){gen=infos[i].generator
+if(!gparm){parm=gparm={attack:.001,hold:.001,decay:.001,sustain:0}}else{parm=Object.create(gparm)
+if(!gen.sampleID)
+gparm=parm}
+if(gen.attackVolEnv)
+parm.attack=Math.pow(2,gen.attackVolEnv.amount/1200)
+if(gen.holdVolEnv)
+parm.hold=Math.pow(2,gen.holdVolEnv.amount/1200)
+if(gen.decayVolEnv)
+parm.decay=Math.pow(2,gen.decayVolEnv.amount/1200)/3
+if(gen.sustainVolEnv)
+parm.sustain=gen.sustainVolEnv.amount/1000
+if(gen.sampleModes&&gen.sampleModes.amount&1)
+parm.sm=1
+if(!gen.sampleID)
+continue
+sid=gen.sampleID.amount
+sampleRate=sf2par.sampleHeader[sid].sampleRate
+sample=sf2par.sample[sid]
+parm.buffer=ac.createBuffer(1,sample.length,sampleRate)
+parm.hold+=parm.attack
+parm.decay+=parm.hold
+if(parm.sustain>=.4)
+parm.sustain=0.01
+else
+parm.sustain=1-parm.sustain/.4
+sample_cp(parm.buffer,sample)
+if(parm.sm){parm.loopStart=sf2par.sampleHeader[sid].startLoop/sampleRate
+parm.loopEnd=sf2par.sampleHeader[sid].endLoop/sampleRate}
+scale=(gen.scaleTuning?gen.scaleTuning.amount:100)/100,tune=(gen.coarseTune?gen.coarseTune.amount:0)+
+(gen.fineTune?gen.fineTune.amount:0)/100+
+sf2par.sampleHeader[sid].pitchCorrection/100-
+(gen.overridingRootKey?gen.overridingRootKey.amount:sf2par.sampleHeader[sid].originalPitch)
+for(j=gen.keyRange.lo;j<=gen.keyRange.hi;j++){rates[instr][j]=Math.pow(Math.pow(2,1/12),(j+tune)*scale)
+params[instr][j]=parm}}}}
+function load_instr(instr){w_instr++
+abc2svg.loadjs(conf.sfu+'/'+instr+'.js',function(){var sf2par=new sf2.Parser(b64dcod(abcsf2[instr]))
+sf2par.parse()
+var sf2pre=sf2par.getPresets()
+sf2_create(instr,sf2par,sf2pre)
+if(--w_instr==0)
+play_start()},function(){errmsg('could not find the instrument '+
+((instr/128)|0).toString()+'-'+
+(instr%128).toString())
+if(--w_instr==0)
+play_start()})}
+function def_instr(s,f,sf2par,sf2pre){var i,bk=[],nv=-1,vb=0
+s=s.p_v.sym
+while(s.ts_prev)
+s=s.ts_prev
+for(;s;s=s.ts_next){if(s.v>nv){nv=s.v
+bk[nv]=0
+if(s.p_v.midictl){if(s.p_v.midictl[0])
+bk[s.v]=(bk[s.v]&~0x1fc000)
++(s.p_v.midictl[0]<<14)
+if(s.p_v.midictl[32])
+bk[s.v]=(bk[s.v]&~0x3f80)
++(s.p_v.midictl[32]<<7)}}
+switch(s.subtype){case"midiprog":break
+case"midictl":if(s.ctrl!=0&&s.ctrl!=32)
+continue
+if(bk[s.v]==undefined)
+bk[s.v]=0
+if(s.ctrl==0)
+bk[s.v]=(bk[s.v]&~0x1fc000)
++(s.val<<14)
+else
+bk[s.v]=(bk[s.v]&~0x3f80)
++(s.val<<7)
+default:continue}
+vb|=1<<s.v
+i=s.instr
+if(i==undefined){if(s.chn!=9)
+continue
+i=bk[s.v]?0:128*128}
+if(bk[s.v])
+i+=bk[s.v]
+if(!params[i]){params[i]=[]
+f(i,sf2par,sf2pre)}}
+nv=(2<<nv)-1
+if(nv!=vb&&!params[0]){params[0]=[]
+f(0,sf2par,sf2pre)}}
+function load_res(s){if(abc2svg.sf2||conf.sfu.slice(-4)==".sf2"||conf.sfu.slice(-3)==".js"){if(abc2svg.sf2){if(!parser){parser=new sf2.Parser(b64dcod(abc2svg.sf2))
+parser.parse()
+presets=parser.getPresets()}}else if(!parser){w_instr++
+if(conf.sfu.slice(-3)==".js"){abc2svg.loadjs(conf.sfu,function(){load_res(s)
+if(--w_instr==0)
+play_start()},function(){errmsg('could not load the sound file '
++conf.sfu)
+if(--w_instr==0)
+play_start()})
+return}
+var r=new XMLHttpRequest()
+r.open('GET',conf.sfu,true)
+r.responseType="arraybuffer"
+r.onload=function(){if(r.status===200){parser=new sf2.Parser(new Uint8Array(r.response))
+parser.parse()
+presets=parser.getPresets()
+load_res(s)
+if(--w_instr==0)
+play_start()}else{errmsg('could not load the sound file '
++conf.sfu)
+if(--w_instr==0)
+play_start()}}
+r.onerror=function(){errmsg('could not load the sound file '
++conf.sfu)
+if(--w_instr==0)
+play_start()}
+r.send()
+return}
+def_instr(s,sf2_create,parser,presets)}else{def_instr(s,load_instr)}}
+function get_time(po){return po.ac.currentTime}
+function midi_ctrl(po,s,t){switch(s.ctrl){case 0:if(po.v_b[s.v]==undefined)
+po.v_b[s.v]=0
+po.v_b[s.v]=(po.v_b[s.v]&~0x1fc000)
++(s.val<<14)
+break
+case 7:s.p_v.vol=s.val/127
+break
+case 32:if(po.v_b[s.v]==undefined)
+po.v_b[s.v]=0
+po.v_b[s.v]=(po.v_b[s.v]&~0x3f80)
++(s.val<<7)
+break}}
+function midi_prog(po,s){var i=s.instr
+po.v_c[s.v]=s.chn
+if(i==undefined){if(s.chn!=9)
+return
+i=po.v_b[s.v]?0:128*128}
+if(po.v_b[s.v])
+i+=po.v_b[s.v]
+po.c_i[s.chn]=i}
+function note_run(po,s,key,t,d){var g,st,c=po.v_c[s.v],instr=po.c_i[c],k=key|0,parm=params[instr][k],o=po.ac.createBufferSource(),v=s.p_v.vol==undefined?1:s.p_v.vol
+if(!v||!parm)
+return
+o.buffer=parm.buffer
+if(parm.loopStart){o.loop=true
+o.loopStart=parm.loopStart
+o.loopEnd=parm.loopEnd}
+if(o.detune){var dt=(key*100)%100
+if(dt)
+o.detune.value=dt}
+o.playbackRate.value=po.rates[instr][k]
+g=po.ac.createGain()
+if(parm.hold<0.002){g.gain.setValueAtTime(v,t)}else{if(parm.attack<0.002){g.gain.setValueAtTime(v,t)}else{g.gain.setValueAtTime(0,t)
+g.gain.linearRampToValueAtTime(v,t+parm.attack)}
+g.gain.setValueAtTime(v,t+parm.hold)}
+g.gain.exponentialRampToValueAtTime(parm.sustain*v,t+parm.decay)
+o.connect(g)
+g.connect(po.gain)
+o.start(t)
+o.stop(t+d)}
+function play_start(){if(po.stop){po.onend(repv)
+return}
+gain.connect(ac.destination)
+abc2svg.play_next(po)}
+init_b64d()
+if(!conf.sfu)
+conf.sfu="Scc1t2"
+if(navigator.userAgentData&&navigator.userAgentData.getHighEntropyValues)
+navigator.userAgentData.getHighEntropyValues(['model']).then(function(ua){model=ua.model})
+else
+model=navigator.userAgent
+return{get_outputs:function(){return(window.AudioContext||window.webkitAudioContext)?['sf2']:null},play:function(i_start,i_end,i_lvl){errmsg=conf.errmsg||alert
+function play_unlock(){var buf=ac.createBuffer(1,1,22050),src=ac.createBufferSource()
+src.buffer=buf
+src.connect(ac.destination)
+src.start(0)}
+if(!gain){ac=conf.ac
+if(!ac){conf.ac=ac=new(window.AudioContext||window.webkitAudioContext)
+if(/iPad|iPhone|iPod/.test(model))
+play_unlock()}
+gain=ac.createGain()
+gain.gain.value=conf.gain}
+while(i_start.noplay)
+i_start=i_start.ts_next
+po={conf:conf,onend:conf.onend||empty,onnote:conf.onnote||empty,s_end:i_end,s_cur:i_start,repv:i_lvl||0,tgen:2,get_time:get_time,midi_ctrl:midi_ctrl,midi_prog:midi_prog,note_run:note_run,timouts:[],v_c:[],c_i:[],v_b:[],ac:ac,gain:gain,rates:rates}
+w_instr++
+load_res(i_start)
+if(--w_instr==0)
+play_start()},stop:function(){po.stop=true
+po.timouts.forEach(function(id){clearTimeout(id)})
+abc2svg.play_next(po)
+if(gain){gain.disconnect()
+gain=null}},set_vol:function(v){if(gain)
+gain.gain.value=v}}}
+(function(root,factory){if(typeof exports==="object"){root.sf2=exports;factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],function(exports){root.sf2=exports;return(root.sf2,factory(exports))})}else{root.sf2={};factory(root.sf2)}}(this,function(sf2){"use strict";sf2.Parser=function(input,options){options=options||{};this.input=input;this.parserOptions=options.parserOptions};sf2.Parser.prototype.parse=function(){var parser=new sf2.Riff.Parser(this.input,this.parserOptions),chunk;parser.parse();if(parser.chunkList.length!==1)
+throw new Error('wrong chunk length');chunk=parser.getChunk(0);if(chunk===null)
+throw new Error('chunk not found');this.parseRiffChunk(chunk);this.input=null};sf2.Parser.prototype.parseRiffChunk=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='RIFF')
+throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='sfbk')
+throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.getNumberOfChunks()!==3)
+throw new Error('invalid sfbk structure');this.parseInfoList(parser.getChunk(0));this.parseSdtaList(parser.getChunk(1));this.parsePdtaList(parser.getChunk(2))};sf2.Parser.prototype.parseInfoList=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='LIST')
+throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='INFO')
+throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse()};sf2.Parser.prototype.parseSdtaList=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='LIST')
+throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='sdta')
+throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.chunkList.length!==1)
+throw new Error('TODO');this.samplingData=parser.getChunk(0)};sf2.Parser.prototype.parsePdtaList=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='LIST')
+throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='pdta')
+throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.getNumberOfChunks()!==9)
+throw new Error('invalid pdta chunk');this.parsePhdr((parser.getChunk(0)));this.parsePbag((parser.getChunk(1)));this.parsePmod((parser.getChunk(2)));this.parsePgen((parser.getChunk(3)));this.parseInst((parser.getChunk(4)));this.parseIbag((parser.getChunk(5)));this.parseImod((parser.getChunk(6)));this.parseIgen((parser.getChunk(7)));this.parseShdr((parser.getChunk(8)))};sf2.Parser.prototype.parsePhdr=function(chunk){var data=this.input,ip=chunk.offset,presetHeader=this.presetHeader=[],size=chunk.offset+chunk.size;if(chunk.type!=='phdr')
+throw new Error('invalid chunk type:'+chunk.type);while(ip<size){presetHeader.push({presetName:String.fromCharCode.apply(null,data.subarray(ip,ip+=20)),preset:data[ip++]|(data[ip++]<<8),bank:data[ip++]|(data[ip++]<<8),presetBagIndex:data[ip++]|(data[ip++]<<8),library:(data[ip++]|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24))>>>0,genre:(data[ip++]|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24))>>>0,morphology:(data[ip++]|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24))>>>0})}};sf2.Parser.prototype.parsePbag=function(chunk){var data=this.input,ip=chunk.offset,presetZone=this.presetZone=[],size=chunk.offset+chunk.size;if(chunk.type!=='pbag')
+throw new Error('invalid chunk type:'+chunk.type);while(ip<size){presetZone.push({presetGeneratorIndex:data[ip++]|(data[ip++]<<8),presetModulatorIndex:data[ip++]|(data[ip++]<<8)})}};sf2.Parser.prototype.parsePmod=function(chunk){if(chunk.type!=='pmod')
+throw new Error('invalid chunk type:'+chunk.type);this.presetZoneModulator=this.parseModulator(chunk)};sf2.Parser.prototype.parsePgen=function(chunk){if(chunk.type!=='pgen')
+throw new Error('invalid chunk type:'+chunk.type);this.presetZoneGenerator=this.parseGenerator(chunk)};sf2.Parser.prototype.parseInst=function(chunk){var data=this.input,ip=chunk.offset,instrument=this.instrument=[],size=chunk.offset+chunk.size;if(chunk.type!=='inst')
+throw new Error('invalid chunk type:'+chunk.type);while(ip<size){instrument.push({instrumentName:String.fromCharCode.apply(null,data.subarray(ip,ip+=20)),instrumentBagIndex:data[ip++]|(data[ip++]<<8)})}};sf2.Parser.prototype.parseIbag=function(chunk){var data=this.input,ip=chunk.offset,instrumentZone=this.instrumentZone=[],size=chunk.offset+chunk.size;if(chunk.type!=='ibag')
+throw new Error('invalid chunk type:'+chunk.type);while(ip<size){instrumentZone.push({instrumentGeneratorIndex:data[ip++]|(data[ip++]<<8),instrumentModulatorIndex:data[ip++]|(data[ip++]<<8)})}};sf2.Parser.prototype.parseImod=function(chunk){if(chunk.type!=='imod')
+throw new Error('invalid chunk type:'+chunk.type);this.instrumentZoneModulator=this.parseModulator(chunk)};sf2.Parser.prototype.parseIgen=function(chunk){if(chunk.type!=='igen')
+throw new Error('invalid chunk type:'+chunk.type);this.instrumentZoneGenerator=this.parseGenerator(chunk)};sf2.Parser.prototype.parseShdr=function(chunk){var data=this.input,ip=chunk.offset,samples=this.sample=[],sampleHeader=this.sampleHeader=[],size=chunk.offset+chunk.size,sampleName,start,end,startLoop,endLoop,sampleRate,originalPitch,pitchCorrection,sampleLink,sampleType;if(chunk.type!=='shdr')
+throw new Error('invalid chunk type:'+chunk.type);while(ip<size){sampleName=String.fromCharCode.apply(null,data.subarray(ip,ip+=20));start=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);end=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);startLoop=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);endLoop=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);sampleRate=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);originalPitch=data[ip++];pitchCorrection=(data[ip++]<<24)>>24;sampleLink=data[ip++]|(data[ip++]<<8);sampleType=data[ip++]|(data[ip++]<<8);var sample=new Int16Array(new Uint8Array(data.subarray(this.samplingData.offset+start*2,this.samplingData.offset+end*2)).buffer);startLoop-=start;endLoop-=start;if(sampleRate>0){var adjust=this.adjustSampleData(sample,sampleRate);sample=adjust.sample;sampleRate*=adjust.multiply;startLoop*=adjust.multiply;endLoop*=adjust.multiply}
+samples.push(sample);sampleHeader.push({sampleName:sampleName,startLoop:startLoop,endLoop:endLoop,sampleRate:sampleRate,originalPitch:originalPitch,pitchCorrection:pitchCorrection,sampleLink:sampleLink,sampleType:sampleType})}};sf2.Parser.prototype.adjustSampleData=function(sample,sampleRate){var newSample,i,il,j,multiply=1;while(sampleRate<22050){newSample=new Int16Array(sample.length*2);for(i=j=0,il=sample.length;i<il;++i){newSample[j++]=sample[i];newSample[j++]=sample[i]}
+sample=newSample;multiply*=2;sampleRate*=2}
+return{sample:sample,multiply:multiply}};sf2.Parser.prototype.parseModulator=function(chunk){var data=this.input,ip=chunk.offset,size=chunk.offset+chunk.size,code,key,output=[];while(ip<size){ip+=2;code=data[ip++]|(data[ip++]<<8);key=sf2.Parser.GeneratorEnumeratorTable[code];if(key===undefined){output.push({type:key,value:{code:code,amount:data[ip]|(data[ip+1]<<8)<<16>>16,lo:data[ip++],hi:data[ip++]}})}else{switch(key){case'keyRange':case'velRange':case'keynum':case'velocity':output.push({type:key,value:{lo:data[ip++],hi:data[ip++]}});break;default:output.push({type:key,value:{amount:data[ip++]|(data[ip++]<<8)<<16>>16}});break}}
+ip+=2;ip+=2}
+return output};sf2.Parser.prototype.parseGenerator=function(chunk){var data=this.input,ip=chunk.offset,size=chunk.offset+chunk.size,code,key,output=[];while(ip<size){code=data[ip++]|(data[ip++]<<8);key=sf2.Parser.GeneratorEnumeratorTable[code];if(key===undefined){output.push({type:key,value:{code:code,amount:data[ip]|(data[ip+1]<<8)<<16>>16,lo:data[ip++],hi:data[ip++]}});continue}
+switch(key){case'keynum':case'keyRange':case'velRange':case'velocity':output.push({type:key,value:{lo:data[ip++],hi:data[ip++]}});break;default:output.push({type:key,value:{amount:data[ip++]|(data[ip++]<<8)<<16>>16}});break}}
+return output};sf2.Parser.prototype.getPresets=function(){var preset=this.presetHeader,zone=this.presetZone,output=[],bagIndex,bagIndexEnd,zoneInfo,presetGenerator,presetModulator,i,il,j,jl
+for(i=0,il=preset.length;i<il;++i){j=preset[i].presetBagIndex
+jl=preset[i+1]?preset[i+1].presetBagIndex:zone.length
+zoneInfo=[];for(;j<jl;++j){presetGenerator=this.createPresetGenerator_(zone,j);presetModulator=this.createPresetModulator_(zone,j);zoneInfo.push({generator:presetGenerator.generator,modulator:presetModulator.modulator,})}
+output.push({info:zoneInfo,header:preset[i],})}
+return output};sf2.Parser.prototype.createInstrumentGenerator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].instrumentGeneratorIndex,zone[index+1]?zone[index+1].instrumentGeneratorIndex:this.instrumentZoneGenerator.length,this.instrumentZoneGenerator);return{generator:modgen.modgen,}};sf2.Parser.prototype.createInstrumentModulator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].presetModulatorIndex,zone[index+1]?zone[index+1].instrumentModulatorIndex:this.instrumentZoneModulator.length,this.instrumentZoneModulator);return{modulator:modgen.modgen}};sf2.Parser.prototype.createPresetGenerator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].presetGeneratorIndex,zone[index+1]?zone[index+1].presetGeneratorIndex:this.presetZoneGenerator.length,this.presetZoneGenerator);return{generator:modgen.modgen,}};sf2.Parser.prototype.createPresetModulator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].presetModulatorIndex,zone[index+1]?zone[index+1].presetModulatorIndex:this.presetZoneModulator.length,this.presetZoneModulator);return{modulator:modgen.modgen,}};sf2.Parser.prototype.createBagModGen_=function(zone,indexStart,indexEnd,zoneModGen){var modgen={unknown:[],'keyRange':{hi:127,lo:0}};var info,i,il;for(i=indexStart,il=indexEnd;i<il;++i){info=zoneModGen[i];if(info.type==='unknown')
+modgen.unknown.push(info.value);else
+modgen[info.type]=info.value}
+return{modgen:modgen}};sf2.Parser.GeneratorEnumeratorTable=['startAddrsOffset','endAddrsOffset','startloopAddrsOffset','endloopAddrsOffset','startAddrsCoarseOffset','modLfoToPitch','vibLfoToPitch','modEnvToPitch','initialFilterFc','initialFilterQ','modLfoToFilterFc','modEnvToFilterFc','endAddrsCoarseOffset','modLfoToVolume',undefined,'chorusEffectsSend','reverbEffectsSend','pan',undefined,undefined,undefined,'delayModLFO','freqModLFO','delayVibLFO','freqVibLFO','delayModEnv','attackModEnv','holdModEnv','decayModEnv','sustainModEnv','releaseModEnv','keynumToModEnvHold','keynumToModEnvDecay','delayVolEnv','attackVolEnv','holdVolEnv','decayVolEnv','sustainVolEnv','releaseVolEnv','keynumToVolEnvHold','keynumToVolEnvDecay','instrument',undefined,'keyRange','velRange','startloopAddrsCoarseOffset','keynum','velocity','initialAttenuation',undefined,'endloopAddrsCoarseOffset','coarseTune','fineTune','sampleID','sampleModes',undefined,'scaleTuning','exclusiveClass','overridingRootKey'];sf2.Riff={};sf2.Riff.Parser=function(input,options){options=options||{};this.input=input;this.ip=options.index||0;this.length=options.length||input.length-this.ip;this.offset=this.ip;this.padding=options.padding!==undefined?options.padding:true;this.bigEndian=options.bigEndian!==undefined?options.bigEndian:false};sf2.Riff.Chunk=function(type,size,offset){this.type=type;this.size=size;this.offset=offset};sf2.Riff.Parser.prototype.parse=function(){var length=this.length+this.offset;this.chunkList=[];while(this.ip<length)
+this.parseChunk()};sf2.Riff.Parser.prototype.parseChunk=function(){var input=this.input,ip=this.ip,size;this.chunkList.push(new sf2.Riff.Chunk(String.fromCharCode(input[ip++],input[ip++],input[ip++],input[ip++]),(size=this.bigEndian?((input[ip++]<<24)|(input[ip++]<<16)|(input[ip++]<<8)|(input[ip++])):((input[ip++])|(input[ip++]<<8)|(input[ip++]<<16)|(input[ip++]<<24))),ip));ip+=size;if(this.padding&&((ip-this.offset)&1)===1)
+ip++;this.ip=ip};sf2.Riff.Parser.prototype.getChunk=function(index){var chunk=this.chunkList[index];if(chunk===undefined)
+return null;return chunk};sf2.Riff.Parser.prototype.getNumberOfChunks=function(){return this.chunkList.length};return sf2}));function Midi5(i_conf){var po,conf=i_conf,empty=function(){},rf,op
+function get_time(po){return window.performance.now()/1000}
+function note_run(po,s,k,t,d){var j,a=(k*100)%100,c=po.v_c[s.v],i=po.c_i[c]
+k|=0
+t*=1000
+d*=1000
+if(a&&Midi5.ma.sysexEnabled){po.op.send(new Uint8Array([0xf0,0x7f,0x7f,0x08,0x02,i&0x7f,0x01,k,k,a/.78125,0,0xf7]),t)}
+po.op.send(new Uint8Array([0x90+c,k,127]),t)
+po.op.send(new Uint8Array([0x80+c,k,0]),t+d-20)}
+function midi_ctrl(po,s,t){po.op.send(new Uint8Array([0xb0+po.v_c[s.v],s.ctrl,s.val]),t*1000)}
+function midi_prog(po,s){var i,c=s.chn
+po.v_c[s.v]=c
+if(po.c_i[c]==undefined){po.op.send(new Uint8Array([0xb0+c,121,0]))
+if(0){if(s.p_v.midictl){for(i in s.p_v.midictl)
+po.op.send(new Uint8Array([0xb0+c,i,s.p_v.midictl[i]]))}}}
+i=s.instr
+if(i!=undefined){po.c_i[c]=i
+po.op.send(new Uint8Array([0xc0+c,i&0x7f]))}}
+function send_outputs(access){var o,os,out=[]
+Midi5.ma=access
+if(access&&access.outputs.size>0){os=access.outputs.values()
+while(1){o=os.next()
+if(!o||o.done)
+break
+out.push(o.value.name)}}
+rf(out)}
+return{get_outputs:function(f){if(!navigator.requestMIDIAccess){f()
+return}
+rf=f
+navigator.requestMIDIAccess({sysex:true}).then(send_outputs,function(msg){navigator.requestMIDIAccess().then(send_outputs,function(msg){rf()})})},set_output:function(name){if(!Midi5.ma)
+return
+var o,os=Midi5.ma.outputs.values()
+while(1){o=os.next()
+if(!o||o.done)
+break
+if(o.value.name==name){op=o.value
+break}}},play:function(i_start,i_end,i_lvl){po={conf:conf,onend:conf.onend||empty,onnote:conf.onnote||empty,s_end:i_end,s_cur:i_start,repv:i_lvl||0,tgen:2,get_time:get_time,midi_ctrl:midi_ctrl,midi_prog:midi_prog,note_run:note_run,timouts:[],op:op,v_c:[],c_i:[]}
+if(0){op.send(new Uint8Array([0xf0,0x7f,0x7f,0x08,0x02,0x00,0x01,0x69,0x69,0x00,0,0xf7]),t)}
+abc2svg.play_next(po)},stop:function(){po.stop=true
+po.timouts.forEach(function(id){clearTimeout(id)})
+abc2svg.play_next(po)
+if(op&&op.clear)
+op.clear()}}}
+function follow(abc,user,playconf){var keep_types={note:true,rest:true}
+user.anno_stop=function(type,start,stop,x,y,w,h){if(!keep_types[type])
+return
+abc.out_svg('<rect class="abcr _'+start+'_" x="');abc.out_sxsy(x,'" y="',y);abc.out_svg('" width="'+w.toFixed(2)+'" height="'+abc.sh(h).toFixed(2)+'"/>\n')}
+playconf.onnote=function(i,on){var b,i,e,elts,x=0,y=0
+if(abc2svg.mu)
+elts=abc2svg.mu.d.getElementsByClassName('_'+i+'_')
+else
+elts=document.getElementsByClassName('_'+i+'_')
+if(!elts||!elts.length)
+return
+e=elts[0]
+e.style.fillOpacity=on?0.4:0
+if(on&&!window.no_scroll){b=e.getBoundingClientRect()
+if(b.top<0||b.bottom>window.innerHeight*.8)
+y=b.top-window.innerHeight*.3
+if(b.left<0||b.right>window.innerWidth*.8)
+x=b.left-window.innerWidth*.3
+if(x||y)
+window.scrollBy({top:y,left:x,behavior:(x<0||y)?'instant':'smooth'})}}}
+(function(){var sty=document.createElement("style")
+sty.innerHTML=".abcr {fill: #d00000; fill-opacity: 0; z-index: 15}"
+document.head.appendChild(sty)})()
+abc2svg.ch_names={'':["C-E G C+","E-C G C+","G-C E G "],m:["C-e G C+","e-C G C+","G-C e G "],'7':["C-b-E G ","E-C G b ","G-E b C+","b-E G C+"],m7:["C-b-e G ","e-C G b ","G-e b C+","b-e G C+"],m7b5:["C-b-e g ","e-C g b ","g-e b C+","b-e g C+"],M7:["C-B-E G ","E-C G B ","G-E B C+","B-E G C+"],'6':["C-A-E G ","E-C A B ","A-E B C+","B-E A C+"],m6:["C-A-e G ","e-C A B ","A-e B C+","B-e A C+"],aug:["C-E a C+","E-C a C+","a-C E a "],aug7:["C-b-E a ","E-C a b ","a-E b C+","b-E a C+"],dim:["C-E g C+","E-C g C+","g-C E g "],dim7:["C-e g A ","e-C g A ","g-e A C+","A-C e G "],'9':["C-b-E G D+","E-C G b D+","G-E b C+D+","b-E G C+D+","D-G-C E b "],m9:["C-b-e G D+","e-C G b D+","G-e b C+D+","b-e G C+D+","D-G-C e b "],maj9:["C-B-E G D+","E-C G B D+","G-E B C+D+","B-E G C+D+","D-G-C E B "],M9:["C-B-E G D+","E-C G B D+","G-C E B D+","B-E G C+D+","D-G-C E B "],'11':["C-b-E G D+F+","E-C G b D+F+","G-E b C+D+F+","b-E G C+D+F+","D-G-C E b F+","F-D-G-C E b D+"],dim9:["C-A-e g d+","e-C g A d+","g-C e A d+","A-C e g d+","D-g-C e A "],sus4:["C-F G C+","F-C G C+","G-C F G "],sus9:["C-D G C+","D-C G C+","G-C D G "],'7sus4':["C-b-F G ","F-C G b ","G-F b C+","b-C F G "],'7sus9':["C-b-D G ","D-C G b ","G-D b C+","b-C D G "],'5':["C-G C+","G-G C+"]}
+abc2svg.midlet="CdDeEFgGaAbB"
+abc2svg.letmid={C:0,d:1,D:2,e:3,E:4,F:5,g:6,G:7,a:8,A:9,b:10,B:11}
+abc2svg.chord=function(first,voice_tb,cfmt){var chnm,i,k,vch,s,gchon,C=abc2svg.C,trans=48+(cfmt.chord.trans?cfmt.chord.trans*12:0)
+function chcr(b,ch){var i,v,r=[]
+b=abc2svg.midlet[b]
+i=ch.length
+while(--i>0){if(ch[i][0]==b)
+break}
+ch=ch[i]
+for(i=0;i<ch.length;i+=2){v=abc2svg.letmid[ch[i]]
+switch(ch[i+1]){case'+':v+=12;break
+case'-':v-=12;break}
+r.push(v)}
+return r}
+function filter(a_cs){var i,cs,t
+for(i=0;i<a_cs.length;i++){cs=a_cs[i]
+if(cs.type!='g')
+continue
+t=cs.otext
+if(t.slice(-1)==')')
+t=t.replace(/\(.*/,'')
+return t.replace(/\(|\)|\[|\]/g,'')}}
+function gench(sb){var r,ch,b,m,n,not,a=filter(sb.a_gch),s={v:vch.v,p_v:vch,type:C.NOTE,time:sb.time,notes:[]}
+if(!a)
+return
+a=a.match(/([A-GN])([#♯b♭]?)([^/]*)\/?(.*)/)
+if(!a)
+return
+r=abc2svg.letmid[a[1]]
+if(r==undefined){if(a[1]!="N")
+return
+s.type=C.REST
+ch=[0]
+r=0}else{switch(a[2]){case"#":case"♯":r++;break
+case"b":case"♭":r--;break}
+if(!a[3]){ch=chnm[""]}else{ch=abc2svg.ch_alias[a[3]]
+if(ch==undefined)
+ch=a[3]
+ch=chnm[ch]
+if(!ch)
+ch=a[3][0]=='m'?chnm.m:chnm[""]}
+if(a[4]){b=a[4][0].toUpperCase()
+b=abc2svg.letmid[b]
+if(b!=undefined){switch(a[4][1]){case"#":case"♯":b++;if(b>=12)b=0;break
+case"b":case"♭":b--;if(b<0)b=11;break}}}}
+if(b==undefined)
+b=0
+ch=chcr(b,ch)
+n=ch.length
+r+=trans
+if(sb.p_v.tr_snd)
+r+=sb.p_v.tr_snd
+for(m=0;m<n;m++){not={midi:r+ch[m]}
+s.notes.push(not)}
+s.nhd=n-1
+s.prev=vch.last_sym
+vch.last_sym.next=s
+s.ts_next=sb.ts_next
+sb.ts_next=s
+s.ts_prev=sb
+if(s.ts_next)
+s.ts_next.ts_prev=s
+vch.last_sym=s}
+if(cfmt.chord.names){chnm=Object.create(abc2svg.ch_names)
+for(k in cfmt.chord.names){vch=""
+for(i=0;i<cfmt.chord.names[k].length;i++){s=cfmt.chord.names[k][i]
+vch+=abc2svg.midlet[s%12]
+vch+=i==0?"-":(s>=12?"+":" ")}
+chnm[k]=[vch]}}else{chnm=abc2svg.ch_names}
+k=0
+for(i=0;i<voice_tb.length;i++){if(k<voice_tb[i].chn)
+k=voice_tb[i].chn}
+if(k==8)
+k++
+vch={v:voice_tb.length,id:"_chord",time:0,sym:{type:C.BLOCK,subtype:"midiprog",chn:k+1,instr:cfmt.chord.prog||0,time:0,ts_prev:first,ts_next:first.ts_next},vol:cfmt.chord.vol||.6}
+vch.sym.p_v=vch
+vch.sym.v=vch.v
+vch.last_sym=vch.sym
+voice_tb.push(vch)
+first.ts_next=vch.sym
+gchon=cfmt.chord.gchon
+s=first
+while(1){if(!s.ts_next){if(gchon)
+vch.last_sym.dur=s.time-vch.last_sym.time
+break}
+s=s.ts_next
+if(!s.a_gch){if(s.subtype=="midigch"){if(gchon&&!s.on)
+vch.last_sym.dur=s.time-vch.last_sym.time
+gchon=s.on}
+continue}
+if(!gchon)
+continue
+for(i=0;i<s.a_gch.length;i++){gch=s.a_gch[i]
+if(gch.type!='g')
+continue
+vch.last_sym.dur=s.time-vch.last_sym.time
+gench(s)
+break}}}

+ 1984 - 0
public/abc2svg/xml2abc.js

@@ -0,0 +1,1984 @@
+//~ Revision: 118, Copyright (C) 2014-2021: Willem Vree
+//~ This program is free software; you can redistribute it and/or modify it under the terms of the
+//~ Lesser GNU General Public License as published by the Free Software Foundation;
+//~ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+//~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//~ See the Lesser GNU General Public License for more details. <http://www.gnu.org/licenses/lgpl.html>.
+var $jscomp = $jscomp || {};
+$jscomp.scope = {};
+$jscomp.arrayIteratorImpl = function (h) {
+    var u = 0;
+    return function () {
+        return u < h.length ? { done: !1, value: h[u++] } : { done: !0 };
+    };
+};
+$jscomp.arrayIterator = function (h) {
+    return { next: $jscomp.arrayIteratorImpl(h) };
+};
+$jscomp.makeIterator = function (h) {
+    var u = "undefined" != typeof Symbol && Symbol.iterator && h[Symbol.iterator];
+    return u ? u.call(h) : $jscomp.arrayIterator(h);
+};
+$jscomp.ASSUME_ES5 = !1;
+$jscomp.ASSUME_NO_NATIVE_MAP = !1;
+$jscomp.ASSUME_NO_NATIVE_SET = !1;
+$jscomp.SIMPLE_FROUND_POLYFILL = !1;
+$jscomp.defineProperty =
+    $jscomp.ASSUME_ES5 || "function" == typeof Object.defineProperties
+        ? Object.defineProperty
+        : function (h, u, n) {
+            h != Array.prototype && h != Object.prototype && (h[u] = n.value);
+        };
+$jscomp.getGlobal = function (h) {
+    h = [
+        "object" == typeof window && window,
+        "object" == typeof self && self,
+        "object" == typeof global && global,
+        h,
+    ];
+    for (var u = 0; u < h.length; ++u) {
+        var n = h[u];
+        if (n && n.Math == Math) return n;
+    }
+    return globalThis;
+};
+$jscomp.global = $jscomp.getGlobal(this);
+$jscomp.SYMBOL_PREFIX = "jscomp_symbol_";
+$jscomp.initSymbol = function () {
+    $jscomp.initSymbol = function () { };
+    $jscomp.global.Symbol || ($jscomp.global.Symbol = $jscomp.Symbol);
+};
+$jscomp.SymbolClass = function (h, u) {
+    this.$jscomp$symbol$id_ = h;
+    $jscomp.defineProperty(this, "description", { configurable: !0, writable: !0, value: u });
+};
+$jscomp.SymbolClass.prototype.toString = function () {
+    return this.$jscomp$symbol$id_;
+};
+$jscomp.Symbol = (function () {
+    function h(n) {
+        if (this instanceof h) throw new TypeError("Symbol is not a constructor");
+        return new $jscomp.SymbolClass($jscomp.SYMBOL_PREFIX + (n || "") + "_" + u++, n);
+    }
+    var u = 0;
+    return h;
+})();
+$jscomp.initSymbolIterator = function () {
+    $jscomp.initSymbol();
+    var h = $jscomp.global.Symbol.iterator;
+    h || (h = $jscomp.global.Symbol.iterator = $jscomp.global.Symbol("Symbol.iterator"));
+    "function" != typeof Array.prototype[h] &&
+        $jscomp.defineProperty(Array.prototype, h, {
+            configurable: !0,
+            writable: !0,
+            value: function () {
+                return $jscomp.iteratorPrototype($jscomp.arrayIteratorImpl(this));
+            },
+        });
+    $jscomp.initSymbolIterator = function () { };
+};
+$jscomp.initSymbolAsyncIterator = function () {
+    $jscomp.initSymbol();
+    var h = $jscomp.global.Symbol.asyncIterator;
+    h || (h = $jscomp.global.Symbol.asyncIterator = $jscomp.global.Symbol("Symbol.asyncIterator"));
+    $jscomp.initSymbolAsyncIterator = function () { };
+};
+$jscomp.iteratorPrototype = function (h) {
+    $jscomp.initSymbolIterator();
+    h = { next: h };
+    h[$jscomp.global.Symbol.iterator] = function () {
+        return this;
+    };
+    return h;
+};
+$jscomp.iteratorFromArray = function (h, u) {
+    $jscomp.initSymbolIterator();
+    h instanceof String && (h += "");
+    var n = 0,
+        q = {
+            next: function () {
+                if (n < h.length) {
+                    var p = n++;
+                    return { value: u(p, h[p]), done: !1 };
+                }
+                q.next = function () {
+                    return { done: !0, value: void 0 };
+                };
+                return q.next();
+            },
+        };
+    q[Symbol.iterator] = function () {
+        return q;
+    };
+    return q;
+};
+$jscomp.polyfill = function (h, u, n, q) {
+    if (u) {
+        n = $jscomp.global;
+        h = h.split(".");
+        for (q = 0; q < h.length - 1; q++) {
+            var p = h[q];
+            p in n || (n[p] = {});
+            n = n[p];
+        }
+        h = h[h.length - 1];
+        q = n[h];
+        u = u(q);
+        u != q && null != u && $jscomp.defineProperty(n, h, { configurable: !0, writable: !0, value: u });
+    }
+};
+$jscomp.polyfill(
+    "Array.prototype.keys",
+    function (h) {
+        return h
+            ? h
+            : function () {
+                return $jscomp.iteratorFromArray(this, function (h) {
+                    return h;
+                });
+            };
+    },
+    "es6",
+    "es3"
+);
+$jscomp.findInternal = function (h, u, n) {
+    h instanceof String && (h = String(h));
+    for (var q = h.length, p = 0; p < q; p++) {
+        var D = h[p];
+        if (u.call(n, D, p, h)) return { i: p, v: D };
+    }
+    return { i: -1, v: void 0 };
+};
+$jscomp.polyfill(
+    "Array.prototype.find",
+    function (h) {
+        return h
+            ? h
+            : function (h, n) {
+                return $jscomp.findInternal(this, h, n).v;
+            };
+    },
+    "es6",
+    "es3"
+);
+var xml2abc_VERSION = 118,
+    vertaal;
+(function () {
+    function h(a, b) {
+        return Array(a + 1).join(b);
+    }
+    function u(a, b) {
+        for (var c = []; a;) c.push(b), --a;
+        return c;
+    }
+    function n(a, b) {
+        for (var c = 0, d = {}; c < a.length; ++c) d[a[c]] = b[c];
+        return d;
+    }
+    function q(a, b) {
+        var c = a.split(/%[ds]/);
+        c.length > b.length && b.push("");
+        return b
+            .map(function (a, b) {
+                return c[b] + a;
+            })
+            .join("");
+    }
+    function p(a, b) {
+        v.info(q(a, b));
+    }
+    function D(a, b) {
+        return -1 !== a.indexOf(b, a.length - b.length);
+    }
+    function H(a) {
+        return Object.keys(a).map(function (a) {
+            return parseInt(a);
+        });
+    }
+    function M(a, b) {
+        var c = [],
+            d;
+        if (Array.isArray(a)) for (d = 0; d < a.length; ++d) d in a && c.push([d, a[d]]);
+        else for (d in a) c.push([d, a[d]]);
+        c.sort(
+            b
+                ? function (a, b) {
+                    return a[0] - b[0];
+                }
+                : function (a, b) {
+                    return a[1] - b[1] || b[0] - a[0];
+                }
+        );
+        return c;
+    }
+    function N(a) {
+        this.reset();
+        this.ixp = a;
+        this.divs = this.mdur = this.ixm = 0;
+        this.mtr = [4, 4];
+    }
+    function C(a, b) {
+        this.tijd = 0;
+        this.dur = a;
+        this.fact = null;
+        this.tup = [""];
+        this.tupabc = "";
+        this.grace = this.beam = 0;
+        this.before = [];
+        this.after = "";
+        this.ns = b ? [b] : [];
+        this.lyrs = {};
+        this.pos = 0;
+        this.tab = null;
+        this.ntdec = "";
+    }
+    function E(a) {
+        this.tijd = 0;
+        this.str = a;
+        this.pos = 0;
+    }
+    function F() { }
+    function z(a) {
+        this.maxtime = this.tijd = 0;
+        this.gMaten = [];
+        this.gLyrics = [];
+        this.vnums = {};
+        this.cnt = new F();
+        this.vceCnt = 1;
+        this.lastnote = null;
+        this.bpl = a.b;
+        this.cpl = a.n;
+        this.repbra = 0;
+        this.nvlt = a.v;
+    }
+    function G(a, b, c, d) {
+        this.fnmext = a;
+        this.outlist = [];
+        this.infolist = [];
+        this.title = "T:Title";
+        this.key = "none";
+        this.clefs = {};
+        this.mtr = "none";
+        this.tempo = 0;
+        this.tempo_units = [1, 4];
+        this.pad = b;
+        this.X = c + 1;
+        this.denL = d.d;
+        this.volpan = d.m;
+        this.cmpL = [];
+        this.scale = "";
+        this.tstep = d.t;
+        this.stemless = 0;
+        this.rightmargin = this.leftmargin = this.pagewidth = "";
+        this.shiftStem = d.s;
+        this.mnum = d.mnum;
+        4 == d.p.length &&
+            ((this.scale = "" != d.p[0] ? parseFloat(d.p[0]) : ""),
+                (this.pagewidth = "" != d.p[1] ? parseFloat(d.p[1]) : ""),
+                (this.leftmargin = "" != d.p[2] ? parseFloat(d.p[2]) : ""),
+                (this.rightmargin = "" != d.p[3] ? parseFloat(d.p[3]) : ""));
+    }
+    function W(a, b) {
+        if (!a.join("")) return ["", 0];
+        for (var c = [], d = 0; d < a.length; ++d) {
+            var e = a[d];
+            "" == e
+                ? (e = b ? "_" : "*")
+                : D(e, "_") && !D(e, "\\_")
+                    ? ((e = e.replace("_", "")), (b = 1))
+                    : (b = 0);
+            c.push(e);
+        }
+        return [c.join(" "), b];
+    }
+    function I(a, b) {
+        for (var c = a, d = b, e; b;) (e = a % b), (a = b), (b = e);
+        return [c / a, d / a];
+    }
+    function O(a, b, c) {
+        if (0 == a.dur) return "";
+        var d = I(c * a.dur, 4 * b);
+        b = d[0];
+        c = d[1];
+        a.fact && ((d = a.fact[0]), (a = a.fact[1]), (d = I(b * d, c * a)), (b = d[0]), (c = d[1]));
+        64 < c &&
+            ((a = b / c),
+                (d = Math.floor(a)),
+                a - d < 0.1 * a && ((b = d), (c = 1)),
+                (d = I(Math.round((64 * b) / c) || 1, 64)),
+                p("denominator too small: %d/%d rounded to %d/%d", [b, c, d[0], d[1]]),
+                (b = d[0]),
+                (c = d[1]));
+        return 1 == b ? (1 == c ? "" : 2 == c ? "/" : "/" + c) : 1 == c ? "" + b : b + "/" + c;
+    }
+    function P(a) {
+        var b = a.match(/([_^]*)([A-Ga-g])([',]*)/);
+        if (!b) return -1;
+        a = b[1];
+        var c = b[2];
+        b = b[3];
+        var d = c.toUpperCase();
+        c = 60 + [0, 2, 4, 5, 7, 9, 11]["CDEFGAB".indexOf(d)] + (d != c ? 12 : 0);
+        a && (c += ("^" == a[0] ? 1 : -1) * a.length);
+        b && (c += ("'" == b[0] ? 12 : -12) * b.length);
+        return c;
+    }
+    function X(a, b, c, d) {
+        var e = 0;
+        0 <= c.indexOf("stafflines=1") && (e += 4);
+        !d && 0 <= c.indexOf("bass") && (e += 12);
+        e && ((c = "CDEFGAB".split("")), (e = c.indexOf(a) + e), (a = c[e % 7]), (b += Math.floor(e / 7)));
+        4 < b && (a = a.toLowerCase());
+        5 < b && (a += h(b - 5, "'"));
+        4 > b && (a += h(4 - b, ","));
+        return a;
+    }
+    function Y(a, b) {
+        var c = {
+            maj: 8,
+            ion: 8,
+            m: 11,
+            min: 11,
+            aeo: 11,
+            mix: 9,
+            dor: 10,
+            phr: 12,
+            lyd: 7,
+            loc: 13,
+            non: 8,
+        };
+        b = b.slice(0, 3).toLowerCase();
+        b =
+            "Fb Cb Gb Db Ab Eb Bb F C G D A E B F# C# G# D# A# E# B#".split(" ")[c[b] + a] +
+            (8 != c[b] ? b : "");
+        c = "FCGDAEB".split("");
+        a = 0 <= a ? n(c.slice(0, a), u(a, 1)) : n(c.slice(a), u(-a, -1));
+        return [b, a];
+    }
+    function Q(a, b, c) {
+        var d = 0,
+            e = b[a];
+        var g = e.tup.indexOf("start");
+        -1 < g && e.tup.splice(g, 1);
+        var f = a;
+        for (c = [e.fact[0] / c[0], e.fact[1] / c[1]]; a < b.length;) {
+            e = b[a];
+            if (!(e instanceof E || e.grace)) {
+                -1 < e.tup.indexOf("start")
+                    ? ((g = Q(a, b, c)), (a = g[0]), (g = g[1]), (d += g))
+                    : e.fact && (d += 1);
+                g = e.tup.indexOf("stop");
+                if (-1 < g) {
+                    e.tup.splice(g, 1);
+                    break;
+                }
+                if (!e.fact) {
+                    a = l;
+                    break;
+                }
+                var l = a;
+            }
+            a += 1;
+        }
+        l = [c[0], c[1], d];
+        l = "3,2,3" == l.toString() ? "(3" : q("(%d:%d:%d", l);
+        b[f].tupabc = l + b[f].tupabc;
+        return [a, d];
+    }
+    function Z(a) {
+        a = a.filter(function (a) {
+            return a instanceof C;
+        });
+        for (var b = 0; b < a.length - 1;) {
+            var c = a[b],
+                d = a[b + 1];
+            !c.fact &&
+                !d.fact &&
+                0 < c.dur &&
+                d.beam &&
+                (3 * c.dur == d.dur
+                    ? ((d.dur = (2 * d.dur) / 3), (c.dur *= 2), (c.after = "<" + c.after), (b += 1))
+                    : 3 * d.dur == c.dur &&
+                    ((c.dur = (2 * c.dur) / 3), (d.dur *= 2), (c.after = ">" + c.after), (b += 1)));
+            b += 1;
+        }
+    }
+    function aa(a, b, c, d, e) {
+        for (d = 0; d < a.length;)
+            (c = a[d]), c instanceof C && c.fact && !c.grace && ((c = Q(d, a, [1, 1])), (d = c[0])), (d += 1);
+        d = [];
+        for (var g, f = 0; f < a.length; ++f) {
+            c = a[f];
+            if (c instanceof C) {
+                var l = O(c, b, e),
+                    k = 1 < c.ns.length;
+                g = c.ns.filter(function (a) {
+                    return D(a, "-");
+                });
+                g = g.map(function (a) {
+                    return a.slice(0, -1);
+                });
+                var m = "";
+                k && g.length == c.ns.length && ((c.ns = g), (m = "-"));
+                g = c.tupabc + c.before.join("");
+                k && (g += "[");
+                g += c.ns.join("");
+                k && (g += "]" + m);
+                D(g, "-") && ((g = g.slice(0, -1)), (m = "-"));
+                g += l + m;
+                g += c.after;
+                c = c.beam;
+            } else c.str instanceof Array && (c.str = c.str[0]), (g = c.str), (c = 1);
+            c ? d.push(g) : d.push(" " + g);
+        }
+        for (d = d.join(""); 0 <= d.indexOf("!ped!!ped!");) d = d.replace(/!ped!!ped!/g, "!ped!");
+        for (; 0 <= d.indexOf("!ped-up!!ped-up!");) d = d.replace(/!ped-up!!ped-up!/g, "!ped-up!");
+        for (; 0 <= d.indexOf("!8va(!!8va)!");) d = d.replace(/!8va\(!!8va\)!/g, "");
+        return d;
+    }
+    function ba(a, b) {
+        a.map(function (a, b) {
+            a.pos = b;
+        });
+        a.sort(function (a, b) {
+            return a.tijd - b.tijd || a.pos - b.pos;
+        });
+        for (var c = 0, d = [], e = [], g = 0; g < a.length; ++g) {
+            var f = a[g];
+            f.tijd > c && K(f.tijd - c, b) && (d.push(new C(f.tijd - c, "x")), e.push(d.length - 1));
+            if (f instanceof E) f.tijd < c && (f.tijd = c), d.push(f), (c = f.tijd);
+            else {
+                if (f.tijd < c) {
+                    if ("z" == f.ns[0]) continue;
+                    var l = d[d.length - 1];
+                    if (l.tijd <= f.tijd)
+                        if ("z" == l.ns[0])
+                            (l.dur = f.tijd - l.tijd),
+                                0 == l.dur && d.pop(),
+                                p("overlap in part %d, measure %d: rest shortened", [b.ixp + 1, b.ixm + 1]);
+                        else {
+                            l.ns = l.ns.concat(f.ns);
+                            p("overlap in part %d, measure %d: added chord", [b.ixp + 1, b.ixm + 1]);
+                            f.dur = f.tijd + f.dur - c;
+                            if (0 >= f.dur) continue;
+                            f.tijd = c;
+                        }
+                    else {
+                        p("overlapping notes in one voice! part %d, measure %d, note %s discarded", [
+                            b.ixp + 1,
+                            b.ixm + 1,
+                            f instanceof C ? f.ns : f.str,
+                        ]);
+                        continue;
+                    }
+                }
+                d.push(f);
+                if (f instanceof C)
+                    if (((c = f.ns[0]), "x" == c || "z" == c)) e.push(d.length - 1);
+                    else if (e.length) {
+                        if (f.beam && !f.grace) for (c = 0; c < e.length; ++c) d[e[c]].beam = f.beam;
+                        e = [];
+                    }
+                c = f.tijd + f.dur;
+            }
+        }
+        0 == c &&
+            p("empty measure in part %d, measure %d, it should contain at least a rest to advance the time!", [
+                b.ixp + 1,
+                b.ixm + 1,
+            ]);
+        return d;
+    }
+    function ca(a) {
+        function b(a) {
+            a = q('<part-group number="%d" type="%s"></part-group>', [a, "stop"]);
+            return $(a, d);
+        }
+        var c,
+            d = a[0];
+        var e = [];
+        var g = [];
+        var f = a.children();
+        for (c = 0; c < f.length; c++)
+            if (((a = $(f[c])), "part-group" == a[0].tagName)) {
+                var l = a.attr("number");
+                var k = a.attr("type");
+                var m = g.indexOf(l);
+                "start" == k
+                    ? -1 < m
+                        ? (e.push(b(l)), e.push(a))
+                        : (e.push(a), g.push(l))
+                    : -1 < m && (g.splice(m, 1), e.push(a));
+            } else e.push(a);
+        for (c = g.length - 1; 0 <= c; --c) (l = g[c]), e.push(b(l));
+        return e;
+    }
+    function J(a, b, c) {
+        if (0 == a.length) return [[], []];
+        var d = a.shift();
+        if ("part-group" == d[0].tagName) {
+            var e = d.attr("number");
+            var g = d.attr("type");
+            if ("start" == g) {
+                g = [];
+                for (f in { "group-symbol": 0, "group-barline": 0, "group-name": 0, "group-abbreviation": 0 })
+                    g.push(d.find(f).text() || "");
+                b[e] = g;
+                c.push(e);
+                var f = J(a, b, c);
+                a = f[0];
+                d = f[1];
+                f = J(d, b, c);
+                b = f[0];
+                c = f[1];
+                return [[a].concat(b), c];
+            }
+            c = c.pop();
+            a.length && "stop" == a[0].attr("type") && e != c && ((f = b[c]), (b[c] = b[e]), (b[e] = f));
+            b = b[e];
+            return [[b], a];
+        }
+        f = J(a, b, c);
+        b = f[0];
+        a = f[1];
+        return [
+            [
+                ["name_tuple", d.find("part-name").text() || "", d.find("part-abbreviation").text() || ""],
+            ].concat(b),
+            a,
+        ];
+    }
+    function R(a) {
+        var b, c;
+        if (0 == a.length) return [];
+        var d = [];
+        for (b = 0; b < a.length; ++b) {
+            var e = a[b];
+            if (1 == e.length) d.push("" + e[0]);
+            else {
+                d.push("(");
+                for (c = 0; c < e.length; ++c) d.push("" + e[c]);
+                d.push(")");
+            }
+            d.push("|");
+        }
+        d.splice(-1, 1);
+        1 < a.length && (d = ["{"].concat(d).concat(["}"]));
+        return d;
+    }
+    function S(a, b, c, d, e, g) {
+        if ("name_tuple" == a[0])
+            (d = d.shift()),
+                b[0] && ((a[1] = b[0] + ":" + a[1]), (a[2] = b[1] + ":" + a[2])),
+                e.push(a),
+                g.push.apply(g, R(d));
+        else if (2 == a.length && "name_tuple" == a[0][0])
+            (d = d.shift()),
+                (c = ["name_tuple", "", ""]),
+                (c[1] = a[0][1] + ":" + a[1][2]),
+                (c[2] = a[0][2] + ":" + a[1][3]),
+                e.push(c),
+                g.push.apply(g, R(d));
+        else {
+            var f = a[a.length - 1];
+            b = f[0];
+            var l = f[1];
+            var k = f[2];
+            f = f[3];
+            l = "yes" == l || c;
+            g.push("brace" == b ? "{" : "[");
+            for (c = 0; c < a.length - 1; ++c) S(a[c], [k, f], l, d, e, g), l && g.push("|");
+            l && g.splice(-1, 1);
+            g.push("brace" == b ? "}" : "]");
+        }
+    }
+    function da(a) {
+        for (var b = "", c = a.children(), d = 0; d < c.length; ++d) {
+            var e = c[d];
+            switch (e.tagName) {
+                case "elision":
+                    b += "~";
+                    break;
+                case "text":
+                    b += $(e).text().replace(/_/g, "\\_").replace(/-/g, "\\-").replace(/ /g, "~");
+            }
+        }
+        if (!b) return b;
+        c = a.find("syllabic").text();
+        if ("begin" == c || "middle" == c) b += "-";
+        a.find("extend").length && (b += "_");
+        return b;
+    }
+    function ea(a) {
+        var b = { diamond: 1, triangle: 1, square: 1, normal: 1 },
+            c = fa,
+            d,
+            e = "default",
+            g = { default: [] },
+            f = { default: [] };
+        a = a.split("\n");
+        for (d = 0; d < a.length; ++d) {
+            var l = a[d];
+            if (0 <= l.indexOf("I:percmap")) {
+                l = l.split(" ").map(function (a) {
+                    return a.trim();
+                });
+                var k = l[4];
+                k in b && (k = k + "+," + k);
+                l = "%%map perc" + e + " " + l[1] + " print=" + l[2] + " midi=" + l[3] + " heads=" + k;
+                g[e].push(l);
+            }
+            0 <= l.indexOf("%%MIDI") && f[e].push(l);
+            0 <= l.indexOf("V:") &&
+                (k = l.match(/V:\s*(\S+)/)) &&
+                ((e = k[1]), e in g || ((g[e] = []), (f[e] = [])));
+        }
+        b = Object.keys(g).sort();
+        for (d = 0; d < b.length; ++d) c = c.concat(g[b[d]]);
+        e = "default";
+        for (d = 0; d < a.length; ++d)
+            (l = a[d]),
+                0 <= l.indexOf("I:percmap") ||
+                0 <= l.indexOf("%%MIDI") ||
+                (0 <= l.indexOf("V:") || 0 <= l.indexOf("K:")
+                    ? ((k = l.match(/V:\s*(\S+)/)) && (e = k[1]),
+                        c.push(l),
+                        e in f && f[e].length && ((c = c.concat(f[e])), delete f[e]),
+                        0 <= l.indexOf("perc") && -1 == l.indexOf("map=") && (l += " map=perc"),
+                        0 <= l.indexOf("map=perc") && 0 < g[e].length && c.push("%%voicemap perc" + e),
+                        0 <= l.indexOf("map=off") && c.push("%%voicemap"))
+                    : c.push(l));
+        return c.join("\n");
+    }
+    function L(a, b) {
+        var c = a;
+        4 < b && (c = a.toLowerCase());
+        5 < b && (c += h(b - 5, "'"));
+        4 > b && (c += h(4 - b, ","));
+        return c;
+    }
+    function K(a, b) {
+        if (a > b.divs / 16) return 1;
+        p("MuseScore bug: incorrect duration, smaller then 1/64! in measure %d, part %d", [b.ixm, b.ixp]);
+        return 0;
+    }
+    function w(a) {
+        this.slurBuf = {};
+        this.dirStk = {};
+        this.ingrace = 0;
+        this.msc = new z(a);
+        this.unfold = a.u;
+        this.ctf = a.c;
+        this.gStfMap = [];
+        this.midiMap = [];
+        this.drumInst = {};
+        this.drumNotes = {};
+        this.instMid = [];
+        this.midDflt = [-1, -1, -1, -91];
+        this.msralts = {};
+        this.curalts = {};
+        this.stfMap = {};
+        this.vce2stf = {};
+        this.clefMap = {};
+        this.curClef = {};
+        this.stemDir = {};
+        this.clefOct = {};
+        this.curStf = {};
+        this.nolbrk = a.x;
+        this.doPageFmt = 1 == a.p.length;
+        this.tstep = a.t;
+        this.dirtov1 = a.v1;
+        this.ped = !a.noped;
+        this.wstems = a.stm;
+        this.pedVce = null;
+        this.repeat_str = {};
+        this.tabVceMap = {};
+        this.koppen = {};
+        this.note_alts = [
+            "=C ^C =D ^D =E =F ^F =G ^G =A ^A =B".split(" "),
+            "^B _D ^^C _E _F ^E _G ^^F _A ^^G _B _C".split(" "),
+            "__D ^^B __E __F ^^D __G ^^E __A _/A __B __C ^^A".split(" "),
+        ];
+        this.step_map = { C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 };
+    }
+    var ha = Math.pow(2, 53),
+        T = {
+            "ornaments>trill-mark": "T",
+            "ornaments>mordent": "M",
+            "ornaments>inverted-mordent": "P",
+            "ornaments>turn": "!turn!",
+            "ornaments>inverted-turn": "!invertedturn!",
+            "technical>up-bow": "u",
+            "technical>down-bow": "v",
+            "technical>harmonic": "!open!",
+            "technical>open-string": "!open!",
+            "technical>stopped": "!plus!",
+            "technical>snap-pizzicato": "!snap!",
+            "technical>thumb-position": "!thumb!",
+            "articulations>accent": "!>!",
+            "articulations>strong-accent": "!^!",
+            "articulations>staccato": ".",
+            "articulations>staccatissimo": "!wedge!",
+            "articulations>scoop": "!slide!",
+            fermata: "!fermata!",
+            arpeggiate: "!arpeggio!",
+            "articulations>tenuto": "!tenuto!",
+            "articulations>spiccato": "!wedge!",
+            "articulations>breath-mark": "!breath!",
+            "articulations>detached-legato": "!tenuto!.",
+        },
+        U = {
+            p: "!p!",
+            pp: "!pp!",
+            ppp: "!ppp!",
+            pppp: "!pppp!",
+            f: "!f!",
+            ff: "!ff!",
+            fff: "!fff!",
+            ffff: "!ffff!",
+            mp: "!mp!",
+            mf: "!mf!",
+            sfz: "!sfz!",
+        },
+        fa =
+            '%%beginsvg\n<defs>,<text id="x" x="-3" y="0">&#xe263;</text>,<text id="x-" x="-3" y="0">&#xe263;</text>,<text id="x+" x="-3" y="0">&#xe263;</text>,<text id="normal" x="-3.7" y="0">&#xe0a3;</text>,<text id="normal-" x="-3.7" y="0">&#xe0a3;</text>,<text id="normal+" x="-3.7" y="0">&#xe0a4;</text>,<g id="circle-x"><text x="-3" y="0">&#xe263;</text><circle r="4" class="stroke"></circle></g>,<g id="circle-x-"><text x="-3" y="0">&#xe263;</text><circle r="4" class="stroke"></circle></g>,<path id="triangle" d="m-4 -3.2l4 6.4 4 -6.4z" class="stroke" style="stroke-width:1.4"></path>,<path id="triangle-" d="m-4 -3.2l4 6.4 4 -6.4z" class="stroke" style="stroke-width:1.4"></path>,<path id="triangle+" d="m-4 -3.2l4 6.4 4 -6.4z" class="stroke" style="fill:#000"></path>,<path id="square" d="m-3.5 3l0 -6.2 7.2 0 0 6.2z" class="stroke" style="stroke-width:1.4"></path>,<path id="square-" d="m-3.5 3l0 -6.2 7.2 0 0 6.2z" class="stroke" style="stroke-width:1.4"></path>,<path id="square+" d="m-3.5 3l0 -6.2 7.2 0 0 6.2z" class="stroke" style="fill:#000"></path>,<path id="diamond" d="m0 -3l4.2 3.2 -4.2 3.2 -4.2 -3.2z" class="stroke" style="stroke-width:1.4"></path>,<path id="diamond-" d="m0 -3l4.2 3.2 -4.2 3.2 -4.2 -3.2z" class="stroke" style="stroke-width:1.4"></path>,<path id="diamond+" d="m0 -3l4.2 3.2 -4.2 3.2 -4.2 -3.2z" class="stroke" style="fill:#000"></path>,</defs>\n%%endsvg'.split(
+                ","
+            ),
+        V =
+            '%%beginsvg\n,<style type="text/css">\n,.bf {font-family:sans-serif; font-size:7px}\n,</style>\n,<defs>\n,<rect id="clr" x="-3" y="-1" width="6" height="5" fill="white"></rect>\n,<rect id="clr2" x="-3" y="-1" width="11" height="5" fill="white"></rect>\n'.split(
+                ","
+            ),
+        v;
+    N.prototype.reset = function () {
+        this.lline = this.attr = "";
+        this.rline = "|";
+        this.lnum = "";
+    };
+    F.prototype.inc = function (a, b) {
+        this.counters[a][b] = (this.counters[a][b] || 0) + 1;
+    };
+    F.prototype.clear = function (a) {
+        a = Object.keys(a);
+        var b = u(a.length, 0);
+        this.counters = { note: n(a, b), nopr: n(a, b), nopt: n(a, b) };
+    };
+    F.prototype.getv = function (a, b) {
+        return this.counters[a][b];
+    };
+    F.prototype.prcnt = function (a) {
+        for (var b in this.counters.note)
+            0 != this.getv("nopr", b) &&
+                p("part %d, voice %d has %d skipped non printable notes", [a, b, this.getv("nopr", b)]),
+                0 != this.getv("nopt", b) &&
+                p("part %d, voice %d has %d notes without pitch", [a, b, this.getv("nopt", b)]),
+                0 == this.getv("note", b) && p("part %d, skipped empty voice %d", [a, b]);
+    };
+    z.prototype.initVoices = function (a) {
+        this.vtimes = {};
+        this.voices = {};
+        this.lyrics = {};
+        for (var b in this.vnums) (this.vtimes[b] = 0), (this.voices[b] = []), (this.lyrics[b] = []);
+        a && this.cnt.clear(this.vnums);
+    };
+    z.prototype.incTime = function (a) {
+        this.tijd += a;
+        0 > this.tijd && (this.tijd = 0);
+        this.tijd > this.maxtime && (this.maxtime = this.tijd);
+    };
+    z.prototype.appendElemCv = function (a, b) {
+        for (var c in a) this.appendElem(c, b);
+    };
+    z.prototype.insertElem = function (a, b) {
+        b = new E(b);
+        b.tijd = 0;
+        this.voices[a].unshift(b);
+    };
+    z.prototype.appendObj = function (a, b, c) {
+        b.tijd = this.tijd;
+        this.voices[a].push(b);
+        this.incTime(c);
+        this.tijd > this.vtimes[a] && (this.vtimes[a] = this.tijd);
+    };
+    z.prototype.appendElemT = function (a, b, c) {
+        b = new E(b);
+        b.tijd = c;
+        this.voices[a].push(b);
+    };
+    z.prototype.appendElem = function (a, b, c) {
+        this.appendObj(a, new E(b), 0);
+        c && this.cnt.inc("note", a);
+    };
+    z.prototype.appendNote = function (a, b, c) {
+        b.ns.push(b.ntdec + c);
+        this.appendObj(a, b, parseInt(b.dur));
+        this.lastnote = b;
+        "z" != c && "x" != c && (this.cnt.inc("note", a), b.grace || this.lyrics[a].push(b.lyrs));
+    };
+    z.prototype.getLastRec = function (a) {
+        return this.gMaten.length ? ((a = this.gMaten[this.gMaten.length - 1][a]), a[a.length - 1]) : null;
+    };
+    z.prototype.getLastMelis = function (a, b) {
+        return this.gLyrics.length && ((a = this.gLyrics[this.gLyrics.length - 1][a]), b in a) ? a[b][1] : 0;
+    };
+    z.prototype.addChord = function (a, b) {
+        for (var c = 0; c < a.before.length; c++) {
+            var d = a.before[c];
+            0 > this.lastnote.before.indexOf(d) && this.lastnote.before.push(d);
+        }
+        this.lastnote.ns.push(a.ntdec + b);
+    };
+    z.prototype.addBar = function (a, b) {
+        b.mdur &&
+            this.maxtime > b.mdur &&
+            p("measure %d in part %d longer than metre", [b.ixm + 1, b.ixp + 1]);
+        this.tijd = this.maxtime;
+        for (var c in this.vnums) {
+            if (b.lline || b.lnum) {
+                var d = this.getLastRec(c);
+                if (d) {
+                    var e = d.str;
+                    b.lline && (e = (e + b.lline).replace(/:\|:/g, "::").replace(/\|\|/g, "|"));
+                    3 == this.nvlt
+                        ? b.ixp + parseInt(c) == Math.min.apply(null, H(this.vnums)) && (e += b.lnum)
+                        : 4 == this.nvlt
+                            ? parseInt(c) == Math.min.apply(null, H(this.vnums)) && (e += b.lnum)
+                            : b.lnum && ((e += b.lnum), (this.repbra = 1));
+                    d.str = e;
+                } else b.lline && this.insertElem(c, "|:");
+            }
+            a && (d = this.getLastRec(c)) && (d.str += a);
+            b.attr && this.insertElem(c, "" + b.attr);
+            this.appendElem(c, " " + b.rline);
+            this.voices[c] = ba(this.voices[c], b);
+            d = this.lyrics[c];
+            e = {};
+            for (
+                var g = d.reduce(function (a, b) {
+                    return a.concat(H(b));
+                }, []),
+                f = Math.max.apply(null, g.concat([0]));
+                0 < f;
+                --f
+            ) {
+                g = d.map(function (a) {
+                    return a[f] || "";
+                });
+                var l = this.getLastMelis(c, f);
+                e[f] = W(g, l);
+            }
+            this.lyrics[c] = e;
+            Z(this.voices[c]);
+        }
+        this.gMaten.push(this.voices);
+        this.gLyrics.push(this.lyrics);
+        this.tijd = this.maxtime = 0;
+        this.initVoices();
+    };
+    z.prototype.outVoices = function (a, b) {
+        var c;
+        var d = {};
+        var e = Math.min.apply(null, H(this.vnums) || [1]);
+        for (c in this.vnums)
+            if (0 != this.cnt.getv("note", c)) {
+                if (v.denL) var g = v.denL;
+                else {
+                    var f, l;
+                    g = c;
+                    var k = this.gMaten;
+                    var m = a;
+                    var B = 0;
+                    var h = ha;
+                    for (var r = [4, 8, 16]; r.length;) {
+                        var t = r.shift(),
+                            q = 0;
+                        for (l = 0; l < k.length; ++l) {
+                            var y = k[l][g];
+                            for (f = 0; f < y.length; ++f) {
+                                var p = y[f];
+                                p instanceof E || 0 == p.dur || (q += O(p, m[l], t).length);
+                            }
+                        }
+                        q < h && ((B = t), (h = q));
+                    }
+                    g = B;
+                }
+                v.cmpL.push(g);
+                f = [];
+                l = {};
+                for (k = 0; k < this.gMaten.length; ++k) {
+                    m = this.gMaten[k][c];
+                    f.push(aa(m, a[k], k, b, g));
+                    m = void 0;
+                    r = this.gLyrics;
+                    if (0 != k)
+                        for (m in ((B = this.gMaten[k][c]), (h = r[k][c]), (r = r[k - 1][c]), r))
+                            if (((t = r[m][1]), !(m in h) && t)) {
+                                t = B;
+                                q = [];
+                                for (y = 0; y < t.length; ++y)
+                                    if (((p = t[y]), p instanceof C && !p.grace)) {
+                                        if ("z" == p.ns[0] || "x" == p.ns[0]) break;
+                                        q.push("_");
+                                    }
+                                (t = q.join(" ")) && (h[m] = [t, 0]);
+                            }
+                    B = this.gLyrics[k][c];
+                    for (n in B)
+                        if (((m = B[n]), (m = m[0]), n in l)) {
+                            for (; l[n].length < k;) l[n].push("");
+                            l[n].push(m);
+                        } else l[n] = u(k, "").concat([m]);
+                }
+                for (n in l) (m = l[n]), (g = f.length - m.length), (l[n] = m.concat(u(g, "")));
+                v.add("V:" + this.vceCnt);
+                this.repbra &&
+                    (1 == this.nvlt && 1 < this.vceCnt && v.add("I:repbra 0"),
+                        2 == this.nvlt && parseInt(c) > e && v.add("I:repbra 0"));
+                0 < this.cpl ? (this.bpl = 0) : 0 == this.bpl && (this.cpl = 100);
+                for (g = 0; f.length;) {
+                    k = 1;
+                    for (
+                        m = f[0];
+                        k < f.length &&
+                        !(0 < this.cpl && m.length + f[k].length >= this.cpl) &&
+                        !(0 < this.bpl && k >= this.bpl);
+
+                    )
+                        (m += f[k]), (k += 1);
+                    g += k;
+                    v.add(m + " %" + g);
+                    f.splice(0, k);
+                    B = M(l, 1);
+                    for (h = 0; h < B.length; ++h) {
+                        m = B[h];
+                        var n = m[0];
+                        m = m[1];
+                        v.add("w: " + m.slice(0, k).join("|") + "|");
+                        m.splice(0, k);
+                    }
+                }
+                d[c] = this.vceCnt;
+                this.vceCnt += 1;
+            }
+        this.gMaten = [];
+        this.gLyrics = [];
+        this.cnt.prcnt(b + 1);
+        return d;
+    };
+    G.prototype.add = function (a) {
+        this.outlist.push(a + "\n");
+    };
+    G.prototype.info = function (a, b) {
+        this.infolist.push(("undefined" == typeof b || b ? "-- " : "") + a);
+    };
+    G.prototype.mkHeader = function (a, b, c, d, e) {
+        var g = [],
+            f = [],
+            l,
+            k;
+        var m = a.slice();
+        for (k = 0; k < b.length; ++k) {
+            var h = b[k];
+            try {
+                S(h, ["", ""], "", a, g, f);
+            } catch (ia) {
+                p("lousy musicxml: error in part-list", []);
+            }
+        }
+        b = f.join(" ");
+        a = {};
+        for (k = 0; k < m.length && k < g.length; ++k) {
+            var x = m[k];
+            h = g[k];
+            var r = h[1];
+            h = h[2];
+            0 != x.length &&
+                ((x = x[0][0]),
+                    (r = r.replace(/\n/g, "\\n").replace(/\.:/g, ".").replace(/^:|:$/g, "")),
+                    (h = h.replace(/\n/g, "\\n").replace(/\.:/g, ".").replace(/^:|:$/g, "")),
+                    (a[x] = (r ? 'nm="' + r + '"' : "") + (h ? ' snm="' + h + '"' : "")));
+        }
+        g = [
+            q("X:%d\n%s\n%s", [this.X, this.title, -1 < this.mnum ? "%%measurenb " + this.mnum + "\n" : ""]),
+        ];
+        "" !== this.scale && g.push("%%scale " + this.scale + "\n");
+        "" !== this.pagewidth && g.push("%%pagewidth " + this.pagewidth + "cm\n");
+        "" !== this.leftmargin && g.push("%%leftmargin " + this.leftmargin + "cm\n");
+        "" !== this.rightmargin && g.push("%%rightmargin " + this.rightmargin + "cm\n");
+        b && 1 < f.length && g.push("%%score " + b + "\n");
+        m = this.tempo ? q("Q:%d/%d=%s\n", [this.tempo_units[0], this.tempo_units[1], this.tempo]) : "";
+        f = [];
+        for (k = 0; k < this.cmpL.length; ++k) (h = this.cmpL[k]), (f[h] = (f[h] || 0) + 1);
+        f = M(f);
+        f = f[f.length - 1][0];
+        f = this.denL ? this.denL : f;
+        g.push(q("L:1/%d\n%sM:%s\n", [f, m, this.mtr]));
+        g.push(q("I:linebreak $\nK:%s\n", [this.key]));
+        this.stemless && g.push("U:s=!stemless!\n");
+        m = Object.keys(d).sort();
+        for (k = 0; k < m.length; ++k) g = g.concat(d[m[k]]);
+        this.dojef = 0;
+        for (l in this.clefs) {
+            h = c[l - 1];
+            k = h[0];
+            b = h[1];
+            r = h[2];
+            x = h[3];
+            m = h.slice(4);
+            h = this.clefs[l];
+            m.length && 0 > h.indexOf("perc") && (h = (h + " map=perc").trim());
+            g.push(q("V:%d %s %s\n", [l, h, a[l] || ""]));
+            l in d &&
+                (g.push(q("%%voicemap tab%d\n", [l])),
+                    g.push("K:none\nM:none\n%%clef none\n%%staffscale 1.6\n%%flatbeams true\n%%stemdir down\n"));
+            -1 < h.indexOf("perc") && g.push("K:none\n");
+            1 < this.volpan
+                ? (0 < k && k != l && g.push("%%MIDI channel " + k + "\n"),
+                    0 < b && g.push("%%MIDI program " + (b - 1) + "\n"),
+                    0 <= r && g.push("%%MIDI control 7 " + r + "\n"),
+                    0 <= x && g.push("%%MIDI control 10 " + x + "\n"))
+                : 0 < this.volpan &&
+                (m.length && 0 < k && g.push("%%MIDI channel " + k + "\n"),
+                    0 < b && g.push("%%MIDI program " + (b - 1) + "\n"));
+            for (k = 0; k < m.length; ++k)
+                if (
+                    ((h = m[k].nt),
+                        (r = m[k].step),
+                        (b = m[k].midi),
+                        (x = m[k].nhd) || (x = "normal"),
+                        P(h) != b || h != r)
+                )
+                    0 < this.volpan && g.push("%%MIDI drummap " + h + " " + b + "\n"),
+                        g.push("I:percmap " + h + " " + r + " " + b + " " + x + "\n"),
+                        (this.dojef = this.tstep);
+            f != this.cmpL[l - 1] && g.push("L:1/" + this.cmpL[l - 1] + "\n");
+        }
+        this.outlist = g.concat(this.outlist);
+        c = Object.keys(e).sort();
+        if (c.length) {
+            var t = [];
+            var n = this.shiftStem
+                ? '<g id="kop%s" class="bf"><use xlink:href="#clr"></use><text x="-2" y="3">%s</text></g>\n'.replace(
+                    "-2",
+                    "-5"
+                )
+                : '<g id="kop%s" class="bf"><use xlink:href="#clr"></use><text x="-2" y="3">%s</text></g>\n',
+                y = this.shiftStem
+                    ? '<g id="kop%s" class="bf"><use xlink:href="#clr2"></use><text x="-2" y="3">%s</text></g>\n'.replace(
+                        "-2",
+                        "-5"
+                    )
+                    : '<g id="kop%s" class="bf"><use xlink:href="#clr2"></use><text x="-2" y="3">%s</text></g>\n';
+            d = this.shiftStem
+                ? V.map(function (a) {
+                    return a.replace("-3", "-6");
+                })
+                : V;
+            c.forEach(function (a) {
+                t.push(1 < a.length ? q(y, [a, a]) : q(n, [a, a]));
+            });
+            this.outlist = d.concat(t, "</defs>\n%%endsvg\n", this.outlist);
+        }
+    };
+    G.prototype.writeall = function () {
+        var a = v.outlist.join("");
+        this.dojef && (a = ea(a));
+        return [a, this.infolist.join("\n")];
+    };
+    w.prototype.matchSlur = function (a, b, c, d, e, g) {
+        if (-1 != ["start", "stop"].indexOf(a))
+            if ((b || (b = "1"), b in this.slurBuf)) {
+                var f = this.slurBuf[b],
+                    l = f[0],
+                    k = f[1],
+                    m = f[2];
+                f = f[3];
+                a != l
+                    ? (c != k || "start" != l || (f && g) || (m.before.unshift("("), (d.after += ")")),
+                        delete this.slurBuf[b])
+                    : (p("double slur numbers %s-%s in part %d, measure %d, voice %d note %s, first discarded", [
+                        a,
+                        b,
+                        this.msr.ixp + 1,
+                        this.msr.ixm + 1,
+                        c,
+                        d.ns,
+                    ]),
+                        (this.slurBuf[b] = [a, c, d, e]));
+            } else this.slurBuf[b] = [a, c, d, e];
+    };
+    w.prototype.doNotations = function (a, b, c) {
+        for (var d = Object.keys(T).sort(), e = 0; e < d.length; ++e) {
+            var g = d[e],
+                f = T[g];
+            b.find(g).length && a.before.push(f);
+        }
+        e = b.find("ornaments>tremolo");
+        e.length &&
+            ((g = e.attr("type")),
+                (d = h(parseInt(e.text()), "/")),
+                "single" == g
+                    ? a.before.unshift("!" + d + "!")
+                    : ((a.fact = null),
+                        this.tstep
+                            ? "stop" == g && a.before.unshift("!trem" + e.text() + "!")
+                            : "start" == g && a.before.unshift("!" + d + "-!")));
+        d = b.find("technical>fingering");
+        c ||
+            d.each(function () {
+                a.before.push("!" + $(this).text() + "!");
+            });
+        d = b.find("technical>string");
+        d.length &&
+            c &&
+            (this.tstep
+                ? ((c = b.find("technical>fret")), c.length && (a.tab = [d.eq(0).text(), c.eq(0).text()]))
+                : d.each(function () {
+                    var b = "!" + $(this).text() + "!";
+                    0 > a.ntdec.indexOf(b) && (a.ntdec += b);
+                }));
+        c = b.find("ornaments>wavy-line");
+        c = $jscomp.makeIterator(c.toArray());
+        for (d = c.next(); !d.done; d = c.next())
+            switch (((d = d.value), $(d).attr("type"))) {
+                case "start":
+                    a.before.unshift("!trill(!");
+                    break;
+                case "stop":
+                    a.after += "!trill)!";
+            }
+        c = b.find("glissando");
+        0 == c.length && (c = b.find("slide"));
+        c.length &&
+            ((b = "wavy" == c.attr("line-type") ? "~" : "-"),
+                "start" == c.attr("type")
+                    ? a.before.unshift(q("!%s(!", [b]))
+                    : "stop" == c.attr("type") && a.before.unshift(q("!%s)!", [b])));
+    };
+    w.prototype.tabnote = function (a, b, c, d, e) {
+        var g;
+        var f = this.step_map[b] + parseInt(a || "0");
+        11 < f && ((c += 1), (f -= 12));
+        0 > f && (--c, (f += 12));
+        a = e.tab[0];
+        b = e.tab[1];
+        for (g = 0; 4 > g; ++g) {
+            var l = this.note_alts[g % 3][f];
+            var k = c;
+            -1 < ["^B", "^^B"].indexOf(l) && --k;
+            -1 < ["_C", "__C"].indexOf(l) && (k += 1);
+            if (-1 < l.indexOf("/") || 3 == g) k = 9;
+            l = L(l, k);
+            var m = this.tabmap[[d, l]] || ["", ""];
+            k = m[0];
+            m = m[1];
+            if (!k) break;
+            if (a == k) return l;
+            3 == g &&
+                (p("rejected: voice %d note %s string %s fret %s remains: string %s fret %s", [
+                    d,
+                    l,
+                    a,
+                    b,
+                    k,
+                    m,
+                ]),
+                    (e.tab = [k, m]));
+        }
+        this.tabmap[[d, l]] = e.tab;
+        return l;
+    };
+    w.prototype.ntAbc = function (a, b, c, d, e, g) {
+        var f = {
+            "double-flat": -2,
+            "flat-flat": -2,
+            flat: -1,
+            natural: 0,
+            sharp: 1,
+            "sharp-sharp": 2,
+            "double-sharp": 2,
+        };
+        b += this.clefOct[this.curStf[d]] || 0;
+        var l = c.find("accidental").text(),
+            k = c.find("pitch>alter").text();
+        if (e.tab) return this.tabnote(k, a, b, d, e);
+        g &&
+            this.tstep &&
+            ((e = ["__", "_", "", "^", "^^"][parseInt(k || "0") + 2] + L(a, b)),
+                p("no string notation found for note %s in voice %d", [e, d]));
+        b = L(a, b);
+        !k && this.msralts[a] && (k = 0);
+        e = b + "#" + d;
+        !k && e in this.curalts && (k = 0);
+        if ("" === l && "" === k) return b;
+        if ("" != l) k = f[l];
+        else {
+            k = parseFloat(k);
+            if (e in this.curalts) {
+                if (k == this.curalts[e]) return b;
+            } else if (k == (this.msralts[a] || 0)) return b;
+            if (
+                c
+                    .find("tie")
+                    .add(c.find("notations>tied"))
+                    .get()
+                    .some(function (a) {
+                        return "stop" == $(a).attr("type");
+                    })
+            )
+                return b;
+            p("accidental %d added in part %d, measure %d, voice %d note %s", [
+                k,
+                this.msr.ixp + 1,
+                this.msr.ixm + 1,
+                d + 1,
+                b,
+            ]);
+        }
+        this.curalts[e] = k;
+        return (b = ["__", "_", "=", "^", "^^"][k + 2] + b);
+    };
+    w.prototype.doNote = function (a) {
+        var b = new C(0, null),
+            c = parseInt(a.find("voice").text() || "1");
+        this.isSib && (c += 100 * (a.find("staff").text() || 1));
+        var d = 0 < a.find("chord").length,
+            e = a.find("pitch>step").text() || a.find("unpitched>display-step").text(),
+            g = a.find("pitch>octave").text() || a.find("unpitched>display-octave").text(),
+            f = 0 < a.find("rest").length,
+            l = a.find("time-modification>actual-notes").text();
+        if (l) {
+            var k = a.find("time-modification>normal-notes").text();
+            b.fact = [parseInt(l), parseInt(k)];
+        }
+        b.tup = a
+            .find("notations>tuplet")
+            .map(function () {
+                return $(this).attr("type");
+            })
+            .get();
+        k = a.find("duration").text();
+        l = a.find("grace");
+        b.grace = 0 < l.length;
+        b.before = [""];
+        b.after = "";
+        b.grace &&
+            !this.ingrace &&
+            ((this.ingrace = 1), (b.before = ["{"]), "yes" == l.attr("slash") && b.before.push("/"));
+        if ((l = !b.grace && this.ingrace)) (this.ingrace = 0), (this.msc.lastnote.after += "}");
+        if (!k || b.grace) k = 0;
+        if (!f && "no" == a.attr("print-object")) {
+            if (d) return;
+            f = 1;
+        }
+        b.dur = parseInt(k);
+        f || (e && g) || (this.msc.cnt.inc("nopt", c), (g = 5), (e = "E"));
+        k = 0 == ((this.curClef && this.curClef[this.curStf[c]]) || "").indexOf("tab");
+        var m = a.find("notations");
+        m.length && this.doNotations(b, m, k);
+        m = a.find("stem");
+        !f &&
+            m.length &&
+            "none" == m.text() &&
+            (!k || c in this.hasStems || this.tstep) &&
+            (b.before.push("s"), (v.stemless = 1));
+        m = a.find("accidental");
+        m.length && "yes" == m.attr("parentheses") && (b.ntdec += "!courtesy!");
+        f = f ? ("no" == a.attr("print-object") || k ? "x" : "z") : this.ntAbc(e, parseInt(g), a, c, b, k);
+        if (a.find("unpitched").length) {
+            k = this.curClef[this.curStf[c]];
+            e = X(e, parseInt(g), k, this.tstep);
+            g = a.find("instrument");
+            g = g.length ? g.attr("id") : "dummyId";
+            g = this.drumInst[g] || P(f);
+            k = a.find("notehead");
+            m = k.text().replace(" ", "-");
+            "x" == m && (f = "^" + f.replace(/\^/g, "").replace(/_/g, ""));
+            if ("circle-x" == m || "diamond" == m || "triangle" == m)
+                f = "_" + f.replace(/\^/g, "").replace(/_/g, "");
+            "yes" == k.attr("filled") && (m += "+");
+            "no" == k.attr("filled") && (m += "-");
+            this.drumNotes[c + ";" + f] = [e, g, m];
+        }
+        e = a.find("tie").add(a.find("notations>tied")).get();
+        e.some(function (a) {
+            return "start" == $(a).attr("type");
+        }) && (f += "-");
+        e = a
+            .find("beam")
+            .map(function () {
+                return $(this).text();
+            })
+            .get();
+        b.beam = -1 < e.indexOf("continue") || -1 < e.indexOf("end") || b.grace;
+        e = a.find("lyric");
+        for (g = k = 0; g < e.length; ++g) {
+            m = $(e[g]);
+            var h = parseInt((m.attr("number") || "1").replace(/^.*verse/, ""));
+            0 == h ? (h = k + 1) : (k = h);
+            b.lyrs[h] = da(m);
+        }
+        e = a.find("stem").text();
+        !this.wstems ||
+            ("up" != e && "down" != e) ||
+            e == this.stemDir[c] ||
+            ((this.stemDir[c] = e), this.msc.appendElem(c, q("[I:stemdir %s]", [e])));
+        d
+            ? this.msc.addChord(b, f)
+            : ((d = parseInt(a.find("staff").text() || "1")),
+                this.curStf[c] != d &&
+                ((e = d - this.curStf[c]),
+                    (this.curStf[c] = d),
+                    this.msc.appendElem(c, "[I:staff " + (0 < e ? "+" : "") + e + "]")),
+                this.msc.appendNote(c, b, f));
+        e = a.find("notations>slur");
+        for (g = 0; g < e.length; ++g)
+            (a = $(e[g])), this.matchSlur(a.attr("type"), a.attr("number"), c, this.msc.lastnote, b.grace, l);
+    };
+    w.prototype.doAttr = function (a) {
+        var b, c;
+        var d = {
+            C1: "alto1",
+            C2: "alto2",
+            C3: "alto",
+            C4: "tenor",
+            F4: "bass",
+            F3: "bass3",
+            G2: "treble",
+            TAB: "tab",
+            percussion: "perc",
+        };
+        if ((b = a.find("divisions").text())) this.msr.divs = parseInt(b);
+        b = parseInt(a.find("transpose>chromatic").text() || "0");
+        var e = a.find("key>fifths").first().text();
+        var g = 0 == this.msc.tijd && 0 == this.msr.ixm;
+        if (e) {
+            var f = Y(parseInt(e), a.find("key>mode").first().text() || "major");
+            e = f[0];
+            this.msralts = f[1];
+            g && !b && "none" == v.key ? (v.key = e) : (e == v.key && g) || (this.msr.attr += "[K:" + e + "]");
+        }
+        if ((e = a.find("time>beats").text())) {
+            f = a.find("time>beat-type").text();
+            var l = e + "/" + f;
+            g ? (v.mtr = l) : (this.msr.attr += "[M:" + l + "]");
+            this.msr.mtr = [parseInt(e), parseInt(f)];
+        }
+        this.msr.mdur = (this.msr.divs * this.msr.mtr[0] * 4) / this.msr.mtr[1];
+        var k = this;
+        a.find("measure-style").each(function () {
+            var a, b, c, d, e;
+            var f = parseInt($(this).attr("number") || "1");
+            var g = k.stfMap[f];
+            $(this)
+                .find("measure-repeat")
+                .each(function () {
+                    a = $(this).attr("type");
+                    "start" == a
+                        ? ((k.repeat_str[f] = [k.msr.ixm, $(this).text()]),
+                            g.forEach(function (a) {
+                                k.msc.insertElem(a, k.repeat_str[f]);
+                            }))
+                        : "stop" == a &&
+                        ((b = k.repeat_str[f][0]),
+                            (d = k.repeat_str[f][1]),
+                            (c = k.msr.ixm - b),
+                            d ? ((e = d + " "), (c /= parseInt(d))) : (e = ""),
+                            (k.repeat_str[f][0] = q("[I:repeat %s%d]", [e, c])),
+                            delete k.repeat_str[f]);
+                });
+        });
+        (e = a.find("transpose>octave-change").text() || "") && (b += 12 * parseInt(e));
+        l = a.find("clef");
+        for (f = 0; f < l.length; f++) {
+            var m = $(l[f]);
+            e = parseInt(m.attr("number") || "1");
+            var h = m.find("sign").text();
+            var x = "percussion" != h && "TAB" != h ? m.find("line").text() || "" : "";
+            x = d[h + x] || "";
+            m = m.find("clef-octave-change").text() || "0";
+            x += { "-2": "-15", "-1": "-8", 1: "+8", 2: "+15" }[m] || "";
+            this.clefOct[e] = -parseInt(m);
+            b && (x += " transpose=" + b);
+            var r = a.find("staff-details");
+            if (r.length && (r.attr("number") || 1) == e) {
+                if ((m = r.find("staff-lines").text()))
+                    (h = "3" == m && "TAB" == h ? "|||" : m),
+                        (x += " stafflines=" + h),
+                        (this.stafflines = parseInt(m));
+                var t = [];
+                r.find("staff-tuning").each(function () {
+                    t.push($(this).find("tuning-step").text() + $(this).find("tuning-octave").text());
+                });
+                t.length && (x += q(" strings=%s", [t.join(",")]));
+                (h = r.find("capo").text()) && (x += q(" capo=%s", [h]));
+            }
+            this.curClef[e] = x;
+            if (g) this.clefMap[e] = x;
+            else
+                for (m = this.stfMap[e], c = 0; c < m.length; ++c) {
+                    r = m[c];
+                    if (e != this.curStf[r]) {
+                        var n = e - this.curStf[r];
+                        this.curStf[r] = e;
+                        h = 0 < n ? "+" : "";
+                        this.msc.appendElem(r, "[I:staff " + h + n + "]");
+                    }
+                    this.msc.appendElem(r, "[K:" + x + "]");
+                }
+        }
+    };
+    w.prototype.findVoice = function (a, b) {
+        var c = b.eq(a);
+        var d = parseInt(c.find("staff").text() || "1");
+        var e = this.stfMap[d];
+        e = e.length ? e[0] : 1;
+        if (this.dirtov1) return { sn: d, v: e, v1: e };
+        for (a += 1; a < b.length; ++a) {
+            c = b.eq(a);
+            if ("note" == c[0].tagName)
+                return (
+                    (b = parseInt(c.find("staff").text() || "1")),
+                    (d = parseInt(c.find("voice").text() || "1")),
+                    this.isSib && (d += 100 * b),
+                    (b = this.vce2stf[d]),
+                    { sn: b, v: d, v1: e }
+                );
+            if ("backup" == c[0].tagName) break;
+        }
+        return { sn: d, v: e, v1: e };
+    };
+    w.prototype.doDirection = function (a, b, c) {
+        function d(a, b, c, d, e) {
+            b &&
+                ((c = 0 <= b.indexOf("!8v") ? a.stfMap[e] : [c]),
+                    c.forEach(function (c) {
+                        null != d
+                            ? a.msc.appendElemT(c, b.replace("(", ")").replace("ped", "ped-up"), d)
+                            : a.msc.appendElem(c, b);
+                    }));
+        }
+        function e(a, b, c, e) {
+            var f = { down: "!8va(!", up: "!8vb(!", crescendo: "!<(!", diminuendo: "!>(!", start: "!ped!" };
+            g = t.attr("type") || "";
+            var k = b + (t.attr("number") || "1");
+            if (g in f)
+                if (((f = f[g]), k in a.dirStk)) {
+                    var l = a.dirStk[k];
+                    delete a.dirStk[k];
+                    "stop" == l.type
+                        ? d(a, f, c, l.tijd, e)
+                        : (p("%s direction %s has no stop in part %d, measure %d, voice %d", [
+                            b,
+                            l.type,
+                            a.msr.ixp + 1,
+                            a.msr.ixm + 1,
+                            c + 1,
+                        ]),
+                            (a.dirStk[k] = { type: g, vs: c }));
+                } else a.dirStk[k] = { type: g, vs: c };
+            else if ("stop" == g)
+                k in a.dirStk
+                    ? ((l = a.dirStk[k]),
+                        delete a.dirStk[k],
+                        (g = l.type),
+                        (c = l.vs),
+                        "stop" == g
+                            ? (p("%s direction %s has double stop in part %d, measure %d, voice %d", [
+                                b,
+                                g,
+                                a.msr.ixp + 1,
+                                a.msr.ixm + 1,
+                                c + 1,
+                            ]),
+                                (f = ""))
+                            : (f = f[l.type].replace("(", ")").replace("ped", "ped-up")))
+                    : ((a.dirStk[k] = { type: "stop", tijd: a.msc.tijd }), (f = ""));
+            else throw "wrong direction type";
+            d(a, f, c, null, e);
+        }
+        var g,
+            f,
+            l,
+            k = "";
+        var m = a.attr("placement");
+        var h = this.findVoice(b, c);
+        c = h.sn;
+        b = h.v;
+        h = h.v1;
+        var x = "",
+            r = { dacapo: "D.C.", dalsegno: "D.S.", tocoda: "dacoda", fine: "fine", coda: "O", segno: "S" };
+        var t = a.find("sound");
+        if (t.length) {
+            var n = t.find("midi-instrument");
+            if (n.length) {
+                var y = t.find("midi-instrument>midi-program").text();
+                var u = t.find("midi-instrument>midi-channel").text();
+                for (l in this.vceInst) this.vceInst[l] == n.attr("id") && (b = l);
+                (l = (y ? y - 1 : u) + "") &&
+                    0 < v.volpan &&
+                    this.msc.appendElem(b, "[I:MIDI= " + (y ? "program" : "channel") + " " + l + "]");
+            }
+            if ((y = t.attr("tempo"))) {
+                y = parseFloat(y).toFixed(0);
+                var w = [1, 4];
+            }
+            for (A in r)
+                if (t.attr(A)) {
+                    x = r[A];
+                    break;
+                }
+        }
+        l = a.children("direction-type");
+        for (r = 0; r < l.length; ++r) {
+            a = $(l[r]);
+            var A = { whole: [1, 1], half: [1, 2], quarter: [1, 4], eighth: [1, 8] };
+            n = a.find("metronome");
+            n.length &&
+                ((t = n.find("beat-unit").text() || ""),
+                    (w = t in A ? A[t] : A.quarter),
+                    n.find("beat-unit-dot").length && (w = I(3 * w[0], 2 * w[1])),
+                    (A = n
+                        .find("per-minute")
+                        .text()
+                        .match(/[.\d]+/)) && (y = A[0]));
+            t = a.find("wedge");
+            t.length && e(this, "wedge", b);
+            A = a.find("words");
+            0 == A.length && (A = a.find("rehearsal"));
+            for (n = 0; n < A.length; ++n) {
+                if (x) {
+                    this.msc.appendElem(b, q("!%s!", [x]), 1);
+                    break;
+                }
+                var z = "below" == m ? "_" : "^";
+                u = $(A[n]);
+                0 > parseFloat(u.attr("default-y") || "0") && (z = "_");
+                k += u.text().replace(/"/g, '\\"').replace(/\n/g, "\\n");
+            }
+            k = k.trim();
+            for (f in U) (A = U[f]), a.find("dynamics>" + f).length && this.msc.appendElem(b, A, 1);
+            a.find("coda").length && this.msc.appendElem(b, "O", 1);
+            a.find("segno").length && this.msc.appendElem(b, "S", 1);
+            t = a.find("octave-shift");
+            t.length && e(this, "octave-shift", b, c);
+            t = a.find("pedal");
+            t.length && this.ped && (this.pedVce || (this.pedVce = b), e(this, "pedal", this.pedVce));
+            "diatonic fretting" == a.find("other-direction").text() && (this.diafret = 1);
+        }
+        y &&
+            ((y = parseFloat(y).toFixed(0)),
+                0 == this.msc.tijd && 0 == this.msr.ixm
+                    ? ((v.tempo = y), (v.tempo_units = w))
+                    : this.msc.appendElem(h, q("[Q:%d/%d=%s]", [w[0], w[1], y])));
+        k && this.msc.appendElem(b, '"' + z + k + '"', 1);
+    };
+    w.prototype.doHarmony = function (a, b, c) {
+        c = this.findVoice(b, c).v;
+        var d = {
+            major: "",
+            minor: "m",
+            augmented: "+",
+            diminished: "dim",
+            dominant: "7",
+            "half-diminished": "m7b5",
+        };
+        b = { major: "maj", dominant: "", minor: "m", diminished: "dim", augmented: "+", suspended: "sus" };
+        var e = {
+            second: "2",
+            fourth: "4",
+            seventh: "7",
+            sixth: "6",
+            ninth: "9",
+            "11th": "11",
+            "13th": "13",
+        };
+        var g = { 1: "#", 0: "", "-1": "b" };
+        var f = a.find("root>root-step", "").text();
+        var l = g[a.find("root>root-alter").text()] || "";
+        var k = "";
+        var m = a.find("kind").text();
+        m in d
+            ? (m = d[m])
+            : -1 < m.indexOf("-")
+                ? ((d = m.split("-")),
+                    (m = d[0]),
+                    (d = d[1]),
+                    (m = (b[m] || "") + (e[d] || "")),
+                    0 == m.indexOf("sus") && ((k = m), (m = "")))
+                : "none" == m && (m = a.find("kind").attr("text"));
+        e = a.find("degree");
+        for (b = 0; b < e.length; ++b)
+            (d = $(e[b])), (m += (g[d.find("degree-alter").text()] || "") + d.find("degree-value").text());
+        m = m.replace("79", "9").replace("713", "13").replace("maj6", "6");
+        a = a.find("bass>bass-step").text() + (g[a.find("bass>bass-alter").text()] || "");
+        this.msc.appendElem(c, '"' + f + l + m + k + (a && "/" + a) + '"', 1);
+    };
+    w.prototype.doBarline = function (a) {
+        var b = a.find("repeat"),
+            c = 0;
+        b.length && (c = b.attr("direction"));
+        if (this.unfold) return c ? ("forward" == c ? 1 : 2) : 0;
+        "right" == (a.attr("location") || "right") &&
+            ((b = a.find("bar-style").text()),
+                "light-light" == b ? (this.msr.rline = "||") : "light-heavy" == b && (this.msr.rline = "|]"));
+        c && ("forward" == c ? (this.msr.lline = ":") : (this.msr.rline = ":|"));
+        a = a.find("ending");
+        a.length &&
+            ("start" == a.attr("type")
+                ? ((a = (a.attr("number") || "1").replace(/\./g, "").replace(/ /g, "")),
+                    /^[\d,]+$/.test(a) || (a = '"' + a.trim() + '"'),
+                    (this.msr.lnum = a))
+                : "|" == this.msr.rline && (this.msr.rline = "||"));
+        return 0;
+    };
+    w.prototype.doPrint = function (a) {
+        if ("yes" == a.attr("new-system") || "yes" == a.attr("new-page")) return this.nolbrk ? "" : "$";
+    };
+    w.prototype.doPartList = function (a) {
+        var b, c;
+        var d = a.find("part-list>score-part");
+        for (b = 0; b < d.length; ++b) {
+            var e = d[b];
+            var g = {};
+            var f = $(e).find("midi-instrument");
+            for (e = 0; e < f.length; ++e) {
+                var l = $(f[e]);
+                var k = ["midi-channel", "midi-program", "volume", "pan"];
+                var m = [];
+                for (c = 0; c < k.length; ++c) {
+                    var h = k[c];
+                    m.push(l.find(h).text() || this.midDflt[c]);
+                }
+                c = 1 * m[3];
+                -90 <= c && 90 >= c && (c = ((c + 90) / 180) * 127);
+                g[l.attr("id")] = [parseInt(m[0]), parseInt(m[1]), 1.27 * parseFloat(m[2]), c];
+                (m = l.find("midi-unpitched").text()) && (this.drumInst[l.attr("id")] = m - 1);
+            }
+            this.instMid.push(g);
+        }
+        a = a.find("part-list");
+        m = ca(a);
+        return J(m, {}, [])[0];
+    };
+    w.prototype.mkTitle = function (a) {
+        var b = [],
+            c = [],
+            d = [],
+            e,
+            g;
+        var f = a.find("work>work-title").text().trim();
+        var l = a.find("movement-title").text().trim();
+        var k = a.find("identification>creator");
+        for (e = 0; e < k.length; ++e) {
+            var m = $(k[e]);
+            var h = m.text();
+            m = m.attr("type");
+            h &&
+                ((h = h.split("\n").map(function (a) {
+                    return a.trim();
+                })),
+                    "composer" == m
+                        ? b.push.apply(b, h)
+                        : ("lyricist" == m || "transcriber" == m) && c.push.apply(c, h));
+        }
+        k = a.find("identification>rights");
+        for (e = 0; e < k.length; ++e)
+            if ((h = $(k[e]).text()))
+                (h = h.split("\n").map(function (a) {
+                    return a.trim();
+                })),
+                    c.push.apply(c, h);
+        k = a.find("credit");
+        for (e = 0; e < k.length; ++e) {
+            h = "";
+            m = $(k[e]).find("credit-words");
+            for (g = 0; g < m.length; ++g) h += $(m[g]).text();
+            d.push(h.replace(/\s*[\r\n]\s*/g, " "));
+        }
+        d = (function (a) {
+            function e(a) {
+                return a && -1 < h.indexOf(a);
+            }
+            var g = [],
+                k;
+            for (k = 0; k < d.length; ++k) {
+                var h = d[k];
+                (6 > a && ((h && -1 < f.indexOf(h)) || (h && -1 < l.indexOf(h)))) ||
+                    (5 > a && ((h && -1 < b.indexOf(h)) || (h && -1 < c.indexOf(h)))) ||
+                    (4 > a && ((f && -1 < h.indexOf(f)) || (l && -1 < h.indexOf(l)))) ||
+                    (3 > a && (b.some(e) || c.some(e))) ||
+                    (2 > a && /^[\d\W]*$/.test(h)) ||
+                    g.push(h);
+            }
+            0 == a && f + l && (g = "");
+            return g;
+        })(this.ctf);
+        f && (f = "T:" + f.replace(/\n/g, "\nT:") + "\n");
+        l && (f += "T:" + l.replace(/\n/g, "\nT:") + "\n");
+        d.length &&
+            (f +=
+                d
+                    .map(function (a) {
+                        return "T:" + a;
+                    })
+                    .join("\n") + "\n");
+        b.length &&
+            (f +=
+                b
+                    .map(function (a) {
+                        return "C:" + a;
+                    })
+                    .join("\n") + "\n");
+        c.length &&
+            (f +=
+                c
+                    .map(function (a) {
+                        return "Z:" + a;
+                    })
+                    .join("\n") + "\n");
+        f && (v.title = f.substr(0, f.length - 1));
+        (this.isSib = 0 <= a.find("identification>encoding>software").text().indexOf("Sibelius")) &&
+            p("Sibelius MusicXMl is unreliable", []);
+    };
+    w.prototype.doDefaults = function (a) {
+        if (this.doPageFmt) {
+            var b = a.find("defaults");
+            if (b.length) {
+                a = b.find("scaling>millimeters").text();
+                var c = b.find("scaling>tenths").text();
+                c = a / c / 10;
+                a = b.find("page-layout>page-width").text() * c;
+                var d = b.find("page-layout>page-margins").first();
+                b = d.find("left-margin").text();
+                d = d.find("right-margin").text();
+                var e = (10 * c) / 0.2117;
+                !v.scale && e && (v.scale = e.toFixed(2));
+                !v.pagewidth && a && (v.pagewidth = a.toFixed(2));
+                v.leftmargin || "" == b || (v.leftmargin = (b * c).toFixed(2));
+                v.rightmargin || "" == d || (v.rightmargin = (d * c).toFixed(2));
+            }
+        }
+    };
+    w.prototype.locStaffMap = function (a) {
+        var b = {};
+        this.vceInst = {};
+        this.msc.vnums = {};
+        this.hasStems = {};
+        this.stfMap = {};
+        this.clefMap = {};
+        a = a.find("measure>note");
+        for (var c = 0; c < a.length; c++) {
+            var d = $(a[c]),
+                e = parseInt(d.find("voice").text() || "1");
+            this.isSib && (e += 100 * (d.find("staff").text() || 1));
+            this.msc.vnums[e] = 1;
+            var g = parseInt(d.find("staff").text() || "1");
+            this.stfMap[g] = [];
+            if (e in b) {
+                var f = b[e];
+                f[g] = (f[g] || 0) + 1;
+            } else (f = {}), (f[g] = 1), (b[e] = f);
+            f = d.find("instrument");
+            f.length && (this.vceInst[e] = $(f).attr("id"));
+            f = d.find("stem");
+            0 != d.find("rest").length || (0 != f.length && "none" == f.text()) || (this.hasStems[e] = 1);
+        }
+        for (e in b) {
+            a = [];
+            c = b[e];
+            for (g in c) a.push([c[g], g]);
+            a.sort(function (a, b) {
+                return a[0] - b[0];
+            });
+            a = a[a.length - 1][1];
+            this.stfMap[a].push(e);
+            this.vce2stf[e] = a;
+            this.curStf[e] = a;
+        }
+    };
+    w.prototype.addStaffMap = function (a) {
+        var b,
+            c,
+            d = [],
+            e = Object.keys(this.stfMap).sort();
+        for (c = 0; c < e.length; ++c) {
+            var g = e[c];
+            var f = this.stfMap[g];
+            var l = [];
+            var k = [];
+            for (b = 0; b < f.length; ++b) {
+                var h = f[b];
+                h in a && (l.push(a[h]), k.push(void 0 == this.hasStems[h]));
+            }
+            if (l.length)
+                for (d.push(l), f = (g in this.clefMap) ? this.clefMap[g] : "treble", b = 0; b < l.length; ++b)
+                    (h = l[b]),
+                        (g = ""),
+                        0 == f.indexOf("tab") &&
+                        (k[b] && 0 > f.indexOf("nostems") && (g = " nostems"),
+                            this.diafret && 0 > f.indexOf("diafret") && (g += " diafret")),
+                        (v.clefs[h] = f + g);
+        }
+        this.gStfMap.push(d);
+    };
+    w.prototype.addMidiMap = function (a, b) {
+        var c = this.instMid[a],
+            d = Object.keys(c);
+        var e = d.length ? c[d[0]] : this.midDflt;
+        a = [];
+        var g = this;
+        for (m in b) {
+            d = Object.keys(this.drumNotes)
+                .sort()
+                .filter(function (a) {
+                    return a.split(";")[0] == m;
+                });
+            var f = d.map(function (a) {
+                return {
+                    nt: a.split(";")[1],
+                    step: g.drumNotes[a][0],
+                    midi: g.drumNotes[a][1],
+                    nhd: g.drumNotes[a][2],
+                };
+            });
+            var h = b[m];
+            d = this.vceInst[m] || "";
+            d in c ? a.push([h, c[d].concat(f)]) : a.push([h, e.concat(f)]);
+        }
+        a.sort(function (a, b) {
+            return a[0] - b[0];
+        });
+        a.forEach(function (a) {
+            g.midiMap.push(a[1]);
+        });
+        e = "E G B d f a c' e'".split(" ");
+        var k = "0 1- 1 1+ 2 3 3 4 4 5 6 6+ 7 8- 8 8+ 9 10 10 11 11 12 13 13+ 14".split(" ");
+        d = Object.keys(this.tabmap).sort();
+        for (c = 0; c < d.length; ++c) {
+            h = d[c];
+            a = h.match(/(\d+),(.*)/);
+            var m = a[1];
+            var n = a[2];
+            f = this.tabmap[h][0];
+            var p = this.tabmap[h][1];
+            this.diafret && (p = k[parseInt(p)]);
+            h = b[m];
+            f = this.stafflines - parseInt(f);
+            a = this.tabVceMap[h] || [];
+            a.push(q("%%map tab%d %s print=%s heads=kop%s\n", [h, n, e[f], p]));
+            this.tabVceMap[h] = a;
+            this.koppen[p] = 1;
+        }
+    };
+    w.prototype.parse = function (a) {
+        var b = {},
+            c = $(a);
+        this.mkTitle(c);
+        this.doDefaults(c);
+        a = this.doPartList(c);
+        for (var d = c.find("part"), e = 0; e < d.length; ++e) {
+            var g = d.eq(e),
+                f = g.find("measure");
+            this.locStaffMap(g);
+            this.drumNotes = {};
+            this.clefOct = {};
+            this.curClef = {};
+            this.stemDir = {};
+            this.tabmap = {};
+            this.diafret = 0;
+            this.stafflines = 5;
+            this.msc.initVoices(1);
+            var h = 0,
+                k = 0;
+            g = [];
+            for (this.msr = new N(e); this.msr.ixm < f.length;) {
+                var m = f.eq(this.msr.ixm),
+                    n = 0,
+                    u = "";
+                this.msr.reset();
+                this.curalts = {};
+                for (var r = m.children(), t = 0; t < r.length; t++)
+                    switch (((c = r.eq(t)), c[0].tagName)) {
+                        case "note":
+                            this.doNote(c);
+                            break;
+                        case "attributes":
+                            this.doAttr(c);
+                            break;
+                        case "direction":
+                            this.doDirection(c, t, r);
+                            break;
+                        case "sound":
+                            this.doDirection(m, t, r);
+                            break;
+                        case "harmony":
+                            this.doHarmony(c, t, r);
+                            break;
+                        case "barline":
+                            n = this.doBarline(c);
+                            break;
+                        case "backup":
+                            c = parseInt(c.find("duration").text());
+                            K(c, this.msr) && this.msc.incTime(-c);
+                            break;
+                        case "forward":
+                            c = parseInt(c.find("duration").text());
+                            K(c, this.msr) && this.msc.incTime(c);
+                            break;
+                        case "print":
+                            u = this.doPrint(c);
+                    }
+                this.msc.addBar(u, this.msr);
+                g.push(this.msr.divs);
+                1 == n
+                    ? ((k = this.msr.ixm), (this.msr.ixm += 1))
+                    : 2 == n
+                        ? 1 > h
+                            ? ((this.msr.ixm = k), (h += 1))
+                            : ((h = 0), (this.msr.ixm += 1))
+                        : (this.msr.ixm += 1);
+            }
+            for (var w in this.repeat_str) (f = this.repeat_str[w]), (f[0] = q("[I:repeat %s %d]", [f[1], 1]));
+            f = this.msc.outVoices(g, e);
+            this.addStaffMap(f);
+            this.addMidiMap(e, f);
+            for (w in f) b[w] = f[w];
+        }
+        Object.keys(b).length
+            ? v.mkHeader(this.gStfMap, a, this.midiMap, this.tabVceMap, this.koppen)
+            : p("nothing written, %s has no notes ...", [v.fnmext]);
+    };
+    vertaal = function (a, b) {
+        var c = {
+            u: 0,
+            b: 0,
+            n: 0,
+            c: 0,
+            v: 0,
+            d: 0,
+            m: 0,
+            x: 0,
+            t: 0,
+            v1: 0,
+            noped: 0,
+            stm: 0,
+            mnum: -1,
+            p: "f",
+            s: 0,
+        },
+            d;
+        for (d in b) c[d] = b[d];
+        c.p = c.p ? c.p.split(",") : [];
+        v = new G(".abc", "", 0, c);
+        b = new w(c);
+        try {
+            b.parse(a);
+        } catch (e) {
+            p("** exception occurred: %s", [e]);
+        }
+        return v.writeall();
+    };
+})();
+"undefined" != typeof exports &&
+    ((exports.vertaal = vertaal), (exports.xml2abc_VERSION = xml2abc_VERSION));

BIN
public/favicon.ico


+ 55 - 0
public/flexible.js

@@ -0,0 +1,55 @@
+! function (a, b) {
+  function c() {
+    var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
+    var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
+    var b = width > height ? height : width;
+    b / i > 640 && (b = 640 * i);
+    b / i < 420 && (b = 420 * i);
+    var c = b / 10;
+    f.style.fontSize = c + "px", k.rem = a.rem = c
+  }
+  var d, e = a.document,
+    f = e.documentElement,
+    g = e.querySelector('meta[name="viewport"]'),
+    h = e.querySelector('meta[name="flexible"]'),
+    i = 0,
+    j = 0,
+    k = b.flexible || (b.flexible = {});
+  if (g) {
+    console.warn("将根据已有的meta标签来设置缩放比例");
+    var l = g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);
+    l && (j = parseFloat(l[1]), i = parseInt(1 / j))
+  } else if (h) {
+    var m = h.getAttribute("content");
+    if (m) {
+      var n = m.match(/initial\-dpr=([\d\.]+)/),
+        o = m.match(/maximum\-dpr=([\d\.]+)/);
+      n && (i = parseFloat(n[1]), j = parseFloat((1 / i).toFixed(2))), o && (i = parseFloat(o[1]), j = parseFloat((1 / i).toFixed(2)))
+    }
+  }
+  if (!i && !j) {
+    var p = a.navigator.userAgent,
+      q = (!!p.match(/android/gi), !!p.match(/iphone/gi)),
+      r = q && !!p.match(/OS 9_3/),
+      s = a.devicePixelRatio;
+    i = q && !r ? s >= 3 && (!i || i >= 3) ? 3 : s >= 2 && (!i || i >= 2) ? 2 : 1 : 1, j = 1 / i
+  }
+  if (f.setAttribute("data-dpr", i), !g)
+    if (g = e.createElement("meta"), g.setAttribute("name", "viewport"), g.setAttribute("content", "initial-scale=" + j + ", maximum-scale=" + j + ", minimum-scale=" + j + ", user-scalable=no"), f.firstElementChild) f.firstElementChild.appendChild(g);
+    else {
+      var t = e.createElement("div");
+      t.appendChild(g), e.write(t.innerHTML)
+    } a.addEventListener("resize", function () {
+    clearTimeout(d), d = setTimeout(c, 300)
+  }, !1), a.addEventListener("pageshow", function (a) {
+    a.persisted && (clearTimeout(d), d = setTimeout(c, 300))
+  }, !1), "complete" === e.readyState ? e.body.style.fontSize = 12 * i + "px" : e.addEventListener("DOMContentLoaded", function () {
+    e.body.style.fontSize = 12 * i + "px"
+  }, !1), c(), k.dpr = a.dpr = i, k.refreshRem = c, k.rem2px = function (a) {
+    var b = parseFloat(a) * this.rem;
+    return "string" == typeof a && a.match(/rem$/) && (b += "px"), b
+  }, k.px2rem = function (a) {
+    var b = parseFloat(a) / this.rem;
+    return "string" == typeof a && a.match(/px$/) && (b += "rem"), b
+  }
+}(window, window.lib || (window.lib = {}));

+ 11 - 0
public/loading.svg

@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin:auto;display:block;" width="100px" height="100px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
+<circle cx="27.5" cy="57.5" r="5" fill="#01c1b5">
+  <animate attributeName="cy" calcMode="spline" keySplines="0 0.5 0.5 1;0.5 0 1 0.5;0.5 0.5 0.5 0.5" repeatCount="indefinite" values="57.5;42.5;57.5;57.5" keyTimes="0;0.3;0.6;1" dur="1s" begin="-0.6s"></animate>
+</circle> <circle cx="42.5" cy="57.5" r="5" fill="#ff979e">
+  <animate attributeName="cy" calcMode="spline" keySplines="0 0.5 0.5 1;0.5 0 1 0.5;0.5 0.5 0.5 0.5" repeatCount="indefinite" values="57.5;42.5;57.5;57.5" keyTimes="0;0.3;0.6;1" dur="1s" begin="-0.44999999999999996s"></animate>
+</circle> <circle cx="57.5" cy="57.5" r="5" fill="#01c1b5">
+  <animate attributeName="cy" calcMode="spline" keySplines="0 0.5 0.5 1;0.5 0 1 0.5;0.5 0.5 0.5 0.5" repeatCount="indefinite" values="57.5;42.5;57.5;57.5" keyTimes="0;0.3;0.6;1" dur="1s" begin="-0.3s"></animate>
+</circle> <circle cx="72.5" cy="57.5" r="5" fill="#ff979e">
+  <animate attributeName="cy" calcMode="spline" keySplines="0 0.5 0.5 1;0.5 0 1 0.5;0.5 0.5 0.5 0.5" repeatCount="indefinite" values="57.5;42.5;57.5;57.5" keyTimes="0;0.3;0.6;1" dur="1s" begin="-0.15s"></animate>
+</circle>
+</svg>

BIN
public/soundFonts/flute-mp3/A4.mp3


BIN
public/soundFonts/flute-mp3/A5.mp3


BIN
public/soundFonts/flute-mp3/A6.mp3


BIN
public/soundFonts/flute-mp3/Ab4.mp3


BIN
public/soundFonts/flute-mp3/Ab5.mp3


BIN
public/soundFonts/flute-mp3/Ab6.mp3


BIN
public/soundFonts/flute-mp3/B4.mp3


BIN
public/soundFonts/flute-mp3/B5.mp3


BIN
public/soundFonts/flute-mp3/B6.mp3


BIN
public/soundFonts/flute-mp3/Bb4.mp3


BIN
public/soundFonts/flute-mp3/Bb5.mp3


BIN
public/soundFonts/flute-mp3/Bb6.mp3


BIN
public/soundFonts/flute-mp3/C4.mp3


BIN
public/soundFonts/flute-mp3/C5.mp3


BIN
public/soundFonts/flute-mp3/C6.mp3


BIN
public/soundFonts/flute-mp3/C7.mp3


BIN
public/soundFonts/flute-mp3/D4.mp3


BIN
public/soundFonts/flute-mp3/D5.mp3


BIN
public/soundFonts/flute-mp3/D6.mp3


BIN
public/soundFonts/flute-mp3/Db4.mp3


BIN
public/soundFonts/flute-mp3/Db5.mp3


BIN
public/soundFonts/flute-mp3/Db6.mp3


BIN
public/soundFonts/flute-mp3/E4.mp3


BIN
public/soundFonts/flute-mp3/E5.mp3


BIN
public/soundFonts/flute-mp3/E6.mp3


BIN
public/soundFonts/flute-mp3/Eb4.mp3


BIN
public/soundFonts/flute-mp3/Eb5.mp3


BIN
public/soundFonts/flute-mp3/Eb6.mp3


BIN
public/soundFonts/flute-mp3/F4.mp3


BIN
public/soundFonts/flute-mp3/F5.mp3


BIN
public/soundFonts/flute-mp3/F6.mp3


BIN
public/soundFonts/flute-mp3/G4.mp3


BIN
public/soundFonts/flute-mp3/G5.mp3


BIN
public/soundFonts/flute-mp3/G6.mp3


BIN
public/soundFonts/flute-mp3/Gb4.mp3


BIN
public/soundFonts/flute-mp3/Gb5.mp3


BIN
public/soundFonts/flute-mp3/Gb6.mp3


Різницю між файлами не показано, бо вона завелика
+ 0 - 0
src/assets/iconfont.js


+ 1 - 0
src/assets/vue.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 24 - 0
src/components/The-error/index.tsx

@@ -0,0 +1,24 @@
+import { Button, Empty, NavBar } from "vant";
+import { defineComponent } from "vue";
+import { api_back } from "/src/helpers/communication";
+
+export default defineComponent({
+	name: "The-error",
+	setup(props, ctx) {
+		return () => (
+			<div>
+				<NavBar
+                    leftArrow
+					onClickLeft={() => {
+						api_back();
+					}}
+				/>
+				<Empty image="error" description="网络开小差,请稍后重试">
+					<Button type="primary" size="small" onClick={() => history.go(0)}>
+						重新加载
+					</Button>
+				</Empty>
+			</div>
+		);
+	},
+});

+ 7 - 0
src/components/The-icon/index.css

@@ -0,0 +1,7 @@
+.svg-icon {
+    width         : 1em;
+    height        : 1em;
+    position      : relative;
+    fill          : currentColor;
+    vertical-align: -2px;
+}

+ 36 - 0
src/components/The-icon/index.tsx

@@ -0,0 +1,36 @@
+import { PropType, defineComponent } from "vue";
+import "./index.css";
+
+export default defineComponent({
+	name: "TheIcon",
+	props: {
+		iconClassName: {
+			type: String,
+			default: "",
+		},
+		color: {
+			type: String,
+			default: "",
+		},
+		size: {
+			type: Array as PropType<string[]>,
+			default: ["1em", "1em"],
+		},
+	},
+	setup(props) {
+		let width = "1em";
+		let height = "1em";
+		if (Array.isArray(props.size)) {
+			width = props.size[0];
+			height = props.size[1];
+		} else {
+			width = props.size;
+			height = props.size;
+		}
+		return () => (
+			<svg style={{ width, height }} class="svg-icon" aria-hidden="true">
+				<use xlinkHref={"#" + props.iconClassName} fill={props.color} />
+			</svg>
+		);
+	},
+});

+ 0 - 0
src/components/the-audio/index.module.less


+ 20 - 0
src/components/the-audio/index.tsx

@@ -0,0 +1,20 @@
+import { defineComponent, reactive, ref } from "vue";
+import styles from "./index.module.less";
+import { Icon } from "vant";
+export default defineComponent({
+	name: "the-audio",
+    props:{
+        src: {
+            type: String,
+            default: ''
+        }
+    },
+	setup(props) {
+        const videoRef = ref()
+		return () => (
+			<div class={styles.wrap}>
+				<audio ref={videoRef} preload="auto" controls src={props.src}></audio>
+			</div>
+		);
+	},
+});

+ 19 - 0
src/components/the-video/index.module.less

@@ -0,0 +1,19 @@
+.wrap{
+    position: relative;
+    background-color: #fff;
+    border-radius: 14px;
+    width: 50vw;
+    min-height: 40vh;
+    overflow: hidden;
+}
+.video{
+    display: block;
+    width: 100%;
+}
+.playBtn{
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    font-size: 48px;
+}

+ 32 - 0
src/components/the-video/index.tsx

@@ -0,0 +1,32 @@
+import { defineComponent, reactive, ref } from "vue";
+import styles from "./index.module.less";
+import { Icon } from "vant";
+export default defineComponent({
+	name: "the-video",
+    props:{
+        src: {
+            type: String,
+            default: ''
+        }
+    },
+	setup(props) {
+        const videoRef = ref()
+		const videoData = reactive({
+			play: false,
+		});
+        const toggle = () => {
+            videoData.play = !videoData.play
+            if (videoData.play) {
+                videoRef.value?.play()
+            } else {
+                videoRef.value?.pause()
+            }
+        }
+		return () => (
+			<div class={styles.wrap}>
+				<video ref={videoRef} preload="auto" controls class={styles.video} src={props.src}></video>
+				{/* <div class={styles.playBtn} onClick={toggle}>{videoData.play ? <Icon name="pause-circle" /> : <Icon name="play-circle" />}</div> */}
+			</div>
+		);
+	},
+});

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
src/constant/audios.ts


+ 218 - 0
src/constant/instruments.ts

@@ -0,0 +1,218 @@
+const instruments: any = {
+	"Acoustic Grand Piano": "大钢琴",
+	"Bright Acoustic Piano": "明亮的钢琴",
+	"Electric Grand Piano": "电钢琴",
+	"Rhodes Piano": "柔和的电钢琴",
+	"Chorused Piano": "加合唱效果的电钢琴",
+	Harpsichord: "羽管键琴",
+	Clavichord: "科拉维科特琴",
+	Celesta: "钢片琴",
+	Glockenspiel: "钢片琴",
+	"Music box": "八音盒",
+	Vibraphone: "颤音琴",
+	Marimba: "马林巴",
+	Xylophone: "木琴",
+	"Tubular Bells": "管钟",
+	Dulcimer: "大扬琴",
+	"Hammond Organ": "击杆风琴",
+	"Percussive Organ": "打击式风琴",
+	"Rock Organ": "摇滚风琴",
+	"Church Organ": "教堂风琴",
+	"Reed Organ": "簧管风琴",
+	Accordian: "手风琴",
+	Harmonica: "口琴",
+	"Tango Accordian": "探戈手风琴",
+	"Acoustic Guitar": "钢弦吉他",
+	"Electric Guitar": "闷音电吉他",
+	"Overdriven Guitar": "加驱动效果的电吉他",
+	"Distortion Guitar": "加失真效果的电吉他",
+	"Guitar Harmonics": "吉他和音",
+	"Acoustic Bass": "大贝司",
+	"Electric Bass": "电贝司",
+	"Fretless Bass": "无品贝司",
+	"Slap Bass": "掌击",
+	"Synth Bass": "电子合成",
+	Violin: "小提琴",
+	Viola: "中提琴",
+	Cello: "大提琴",
+	Contrabass: "低音大提琴",
+	"Tremolo Strings": "弦乐群颤音音色",
+	"Pizzicato Strings": "弦乐群拨弦音色",
+	"Orchestral Harp": "竖琴",
+	Timpani: "定音鼓",
+	"String Ensemble": "弦乐合奏音色",
+	"Synth Strings": "合成弦乐合奏音色",
+	"Choir Aahs": "人声合唱",
+	"Voice Oohs": "人声",
+	"Synth Voice": "合成人声",
+	"Orchestra Hit": "管弦乐敲击齐奏",
+	Trumpet: "小号",
+	Trombone: "长号",
+	Tuba: "大号",
+	"Muted Trumpet": "加弱音器小号",
+	"French Horn": "法国号",
+	"Brass Section": "铜管组",
+	"Synth Brass": "合成铜管音色",
+	"Soprano Sax": "高音萨克斯管",
+	"Alto Sax": "中音萨克斯管",
+	"Tenor Sax": "次中音萨克斯管",
+	"Baritone Sax": "低音萨克斯管",
+	Oboe: "双簧管",
+	"English Horn": "英国管",
+	Bassoon: "巴松",
+	Clarinet: "单簧管",
+	"Soprano Saxophone": "高音萨克斯管",
+	"Alto Saxophone": "中音萨克斯管",
+	"Tenor Saxophone": "次中音萨克斯管",
+	"Baritone Saxophone": "低音萨克斯管",
+	Piccolo: "短笛",
+	Flute: "长笛",
+	Recorder: "竖笛",
+	"Soprano Recorder": "高音竖笛",
+	"Pan Flute": "排箫",
+	"Bottle Blow": "瓶木管",
+	Whistle: "口哨声",
+	Ocarina: "陶笛",
+	Lead: "合成主音",
+	"Lead lead": "合成主音",
+	"Pad age": "合成音色",
+	Pad: "合成音色",
+	FX: "合成效果  科幻",
+	Sitar: "西塔尔",
+	Banjo: "班卓琴",
+	Shamisen: "三昧线",
+	Koto: "十三弦筝",
+	Kalimba: "卡林巴",
+	Bagpipe: "风笛",
+	Fiddle: "民族提琴",
+	Shanai: "山奈",
+	"Tinkle Bell": "叮当铃",
+	Agogos: "阿戈戈铃",
+	"Steel Drums": "钢鼓",
+	"Taiko Drum": "太鼓",
+	"Melodic Toms": "嗵嗵鼓",
+	"Synth Drums": "合成鼓",
+	"Reverse Cymbals": "反向镲",
+	"Agogo Bells": "阿戈戈铃",
+	"Taiko Drums": "太鼓",
+	Bongos: "邦戈鼓",
+	"Bongo Bell": "邦戈铃",
+	Congas: "康加鼓",
+	Guiro: "刮壶",
+	"Guitar Fret Noise": "吉他换把杂音",
+	"Breath Noise": "呼吸声",
+	Seashore: "海浪声",
+	"Bird Tweet": "鸟鸣",
+	"Telephone Ring": "电话铃",
+	Helicopter: "直升机",
+	Applause: "鼓掌声",
+	Gunshot: "枪声",
+	"Acoustic Bass Drum": "大鼓",
+	"Bass Drum": "大鼓",
+	"Side Drum": "小鼓鼓边",
+	"Acoustic Snare": "小鼓",
+	"Hand Claps": "拍手",
+	"Electric Snare": "小鼓",
+	"Low Floor Tom": "低音嗵鼓",
+	"Closed Hi-Hat": "闭合踩镲",
+	"High Floor Tom": "高音落地嗵鼓",
+	"Pedal Hi-Hat": "脚踏踩镲",
+	"Low Tom": "低音嗵鼓",
+	"Open Hi-Hat": "开音踩镲",
+	"Low-Mid Tom": "中低音嗵鼓",
+	"Hi Mid Tom": "高音鼓",
+	"Crash Cymbals": "对镲",
+	"High Tom": "高音嗵鼓",
+	"Ride Cymbals": "叮叮镲",
+	"Chinese Cymbals": "中国镲",
+	"Ride Bell": "圆铃",
+	Tambourine: "铃鼓",
+	"Splash Cymbal": "溅音镲",
+	Cowbell: "牛铃",
+	"Crash Cymbal": "强音钹",
+	"Vibra-Slap": "颤音器",
+	"Ride Cymbal": "打点钹",
+	"Hi Bongo": "高音邦戈鼓",
+	"Low Bongo": "低音邦戈鼓",
+	"Mute Hi Conga": "弱音高音康加鼓",
+	"Open Hi Conga": "强音高音康加鼓",
+	"Low Conga": "低音康加鼓",
+	"High Timbale": "高音天巴鼓",
+	"Low Timbale": "低音天巴鼓",
+	"High Agogo": "高音阿戈戈铃",
+	"Low Agogo": "低音阿戈戈铃",
+	Cabasa: "卡巴萨",
+	Maracas: "沙锤",
+	"Short Whistle": "短口哨",
+	"Long Whistle": "长口哨",
+	"Short Guiro": "短刮壶",
+	"Long Guiro": "长刮壶",
+	Claves: "响棒",
+	"Hi Wood Block": "高音木鱼",
+	"Low Wood Block": "低音木鱼",
+	"Mute Triangle": "弱音三角铁",
+	"Open Triangle": "强音三角铁",
+	"Drum Set": "架子鼓",
+	"Hulusi flute": "葫芦丝",
+	Melodica: "口风琴",
+	"Snare Drum": "小军鼓",
+	Cymbal: "镲",
+	Cymbals: "镲",
+	"Horn in F": "圆号",
+	Triangle: "三角铁",
+	Vibrato: "颤音琴",
+	"Suspend Cymbals": "吊镲",
+	"Suspended Cymbals": "吊镲",
+	"Tom-Toms": "嗵嗵鼓",
+	Bell: "铃铛",
+	Bells: "铃铛",
+	"Alto Clarinet": "中音单簧管",
+	"Bass Clarinet": "低音单簧管",
+	Cornet: "短号",
+	Euphonium: "上低音号",
+	"crash cymbals": "对镲",
+	Castanets: "响板",
+	Shaker: "沙锤",
+	"Mark tree": "音树",
+	Chimes: "管钟",
+	"Mark Tree": "音树",
+	"Tom-toms": "嗵嗵鼓",
+	"Hi-Hat": "踩镲",
+	"Sleigh Bells": "雪橇铃",
+	Flexatone: "弹音器",
+	"Brake drum": "闸鼓",
+	Gong: "锣",
+	"concert tom": "音乐会嗵嗵鼓",
+	"brake drum": "车轮鼓",
+	"finger cymbal": "指钹",
+	"ride cymbal": "叮叮镲",
+	"Concert Toms": "音乐会嗵嗵鼓",
+	Vibraslap: "弹音器",
+	"Wood Blocks": "木鱼",
+	"Temple Blocks": "木鱼",
+	"Wood Block": "木鱼",
+	"Field Drum": "军鼓",
+	"Quad-Toms": "筒鼓",
+	Quads: "筒鼓",
+	"Drums set": "架子鼓",
+	"High Bongo": "邦戈",
+	Timbales: "天巴鼓",
+};
+/** 获取分轨名称 */
+export const getInstrumentName = (name = '') => {
+  name = name.toLocaleLowerCase().replace(/ /g, '')
+  if (!name) return ''
+  for(let key in instruments){
+    const _key = key.toLocaleLowerCase().replace(/ /g, '')
+    if (_key.includes(name)){
+      return instruments[key]
+    }
+  }
+  for(let key in instruments){
+    const _key = key.toLocaleLowerCase().replace(/ /g, '')
+    if (name.includes(_key)){
+      return instruments[key]
+    }
+  }
+  return ''
+};

+ 215 - 0
src/constant/instrumentsClassfiy.ts

@@ -0,0 +1,215 @@
+const instrumentsClassfiy: any = {
+	"2": ["Flute"],
+	"4": ["Clarinet"],
+	"6": ["Soprano Sax", "Alto Sax", "Tenor Sax", "Baritone Sax", "Soprano Saxophone", "Alto Saxophone", "Tenor Saxophone", "Baritone Saxophone"],
+	"12": ["Trumpet", "Muted Trumpet"],
+	"13": ["Horn in F", "French Horn"],
+	"14": ["Trombone"],
+	"15": ["Euphonium"],
+	"17": ["Tuba"],
+	"23": [
+		"Tinkle Bell",
+		"Agogo",
+		"Steel Drums",
+		"Woodblock",
+		"Taiko Drum",
+		"Melodic Tom",
+		"Synth Drums",
+		"Reverse Cymbals",
+		"Acoustic Bass Drum",
+		"Bass Drum",
+		"Side Drum",
+		"Acoustic Snare",
+		"Hand Claps",
+		"Electric Snare",
+		"Low Floor Tom",
+		"Closed Hi-Hat",
+		"High Floor Tom",
+		"Pedal Hi-Hat",
+		"Low Tom",
+		"Open Hi-Hat",
+		"Low-Mid Tom",
+		"Hi Mid Tom",
+		"Crash Cymbals",
+		"High Tom",
+		"Ride Cymbals",
+		"Chinese Cymbals",
+		"Ride Bell",
+		"Tambourine",
+		"Splash Cymbal",
+		"Cowbell",
+		"Crash Cymbal",
+		"Vibra-Slap",
+		"Ride Cymbal",
+		"Hi Bongo",
+		"Low Bongo",
+		"Mute Hi Conga",
+		"Open Hi Conga",
+		"Low Conga",
+		"High Timbale",
+		"Low Timbale",
+		"High Agogo",
+		"Low Agogo",
+		"Cabasa",
+		"Maracas",
+		"Short Whistle",
+		"Long Whistle",
+		"Short Guiro",
+		"Long Guiro",
+		"Claves",
+		"Hi Wood Block",
+		"Low Wood Block",
+		"Mute",
+		"Open",
+		"Mute Triangle",
+		"Open Triangle",
+		"Snare Drum",
+		"Cymbal",
+		"Cymbals",
+		"Triangle",
+		"Vibrato",
+		"Suspend Cymbals",
+		"Suspended Cymbals",
+		"Tom-Toms",
+		"Bell",
+		"Bells",
+		"crash cymbals",
+		"Suspend cymbals",
+		"Castanets",
+		"Drum Set",
+		"Gong",
+		"Shaker",
+		"Mark tree",
+		"Chimes",
+		"Mark Tree",
+		"Tom-toms",
+		"Hi-Hat",
+		"Sleigh Bells",
+		"Flexatone",
+		"Brake drum",
+		"concert tom",
+		"brake drum",
+		"finger cymbal",
+		"ride cymbal",
+		"Concert Toms",
+		"Vibraslap",
+		"Wood Blocks",
+		"Temple Blocks",
+		"Wood Block",
+	],
+	"134": ["Ocarina"],
+	"135": ["Pan Flute"],
+	"136": ["Hulusi flute"],
+	"137": ["Melodica"],
+	Oboe: ["Oboe"],
+	"English Horn": ["English Horn"],
+	Bassoon: ["Bassoon"],
+	Piccolo: ["Piccolo"],
+	Recorder: ["Recorder"],
+	"Soprano Recorder": ["Soprano Recorder"],
+	DYOther: [
+		"Acoustic Grand Piano",
+		"Bright Acoustic Piano",
+		"Electric Grand Piano",
+		"Rhodes Piano",
+		"Chorused Piano",
+		"Harpsichord",
+		"Clavichord",
+		"Celesta",
+		"Glockenspiel",
+		"Music box",
+		"Vibraphone",
+		"Marimba",
+		"Xylophone",
+		"Tubular Bells",
+		"Dulcimer",
+		"Hammond Organ",
+		"Percussive Organ",
+		"Rock Organ",
+		"Church Organ",
+		"Reed Organ",
+		"Accordian",
+		"Harmonica",
+		"Tango Accordian",
+		"Acoustic Guitar",
+		"Electric Guitar",
+		"Overdriven Guitar",
+		"Distortion Guitar",
+		"Guitar Harmonics",
+		"Acoustic Bass",
+		"Electric Bass",
+		"Fretless Bass",
+		"Slap Bass",
+		"Synth Bass",
+		"Violin",
+		"Viola",
+		"Cello",
+		"Contrabass",
+		"Tremolo Strings",
+		"Pizzicato Strings",
+		"Orchestral Harp",
+		"Timpani",
+		"String Ensemble",
+		"Synth Strings",
+		"Choir Aahs",
+		"Voice Oohs",
+		"Synth Voice",
+		"Orchestra Hit",
+		"Brass Section",
+		"Synth Brass",
+		"Bottle Blow",
+		"Whistle",
+		"Lead",
+		"Lead lead",
+		"Pad age",
+		"Pad",
+		"FX",
+		"Sitar",
+		"Banjo",
+		"Shamisen",
+		"Koto",
+		"Kalimba",
+		"Bagpipe",
+		"Fiddle",
+		"Shanai",
+		"Agogos",
+		"Melodic Toms",
+		"Agogo Bells",
+		"Taiko Drums",
+		"Bongos",
+		"Bongo Bell",
+		"Congas",
+		"Guiro",
+		"Guitar Fret Noise",
+		"Breath Noise",
+		"Seashore",
+		"Bird Tweet",
+		"Telephone Ring",
+		"Helicopter",
+		"Applause",
+		"Gunshot",
+		"Bass Clarinet",
+		"Cornet",
+		"Sleigh Bells",
+		"Field Drum",
+		"Quad-Toms",
+		"Quads",
+		"Drums set",
+		"High Bongo",
+		"Timbales",
+	],
+};
+
+export const getInstrumentsClassfiy = (name: string) => {
+	name = name.toLocaleLowerCase().replaceAll(" ", "");
+	for (let key in instrumentsClassfiy) {
+		const names = instrumentsClassfiy[key];
+		for (let i = 0, len = names.length; i < len; i++) {
+			const _key = names[i].toLocaleLowerCase().replaceAll(" ", "");
+			if (_key.includes(name) || name.includes(_key)) {
+				return key;
+			}
+		}
+	}
+  return 0
+};

Різницю між файлами не показано, бо вона завелика
+ 1 - 0
src/constant/tockAndTick.json


+ 27 - 0
src/constant/whiteUrl.ts

@@ -0,0 +1,27 @@
+import qs from "query-string";
+import { storeData } from "../store";
+
+/** 管乐迷获取 url前缀 */
+export const getRequestHostname = () => {
+	const blank = ["mteadev.dayaedu.com", "mteatest.dayaedu.com", "mteaonline.dayaedu.com"];
+	const webBlank = ["mandev.dayaedu.com", "mantest.dayaedu.com", "manonline.dayaedu.com"];
+
+	if (blank.includes(location.hostname)) {
+		return "/api-teacher";
+	} else if (webBlank.includes(location.hostname)) {
+		return "/api-web";
+	}
+	return "/api-student";
+};
+
+// 后台管理,教学伴奏预览专用参数
+const whiteUrl = () => {
+	const parseSearch: any = qs.parse(location.search);
+	return {
+		"/sysMusicScoreCategories/queryTree": "/eduMusicScore/queryTree",
+		"/sysMusicScoreAccompaniment/queryPage": !parseSearch.platform ? "/eduMusicScore/queryPage" : "/sysMusicScoreAccompaniment/queryPage",
+		"/sysMusicScoreAccompaniment/queryPageLimit": "/eduMusicScore/queryPageLimit",
+		"/sysMusicScoreAccompaniment/querySubjectIds": "/eduMusicScore/querySubjectIds",
+	};
+};
+export default whiteUrl;

+ 7 - 0
src/env.d.ts

@@ -0,0 +1,7 @@
+declare module "*.vue" {
+	import type { DefineComponent } from "vue";
+
+	const vueComponent: DefineComponent<{}, {}, any>;
+
+	export default vueComponent;
+}

+ 267 - 0
src/helpers/calcSpeed.ts

@@ -0,0 +1,267 @@
+import { OpenSheetMusicDisplay, SourceMeasure } from "/osmd-extended/src";
+
+export const noteDuration = {
+	"1/2": 2,
+	w: 1,
+	h: 0.5,
+	q: 0.25,
+	"8": 0.125,
+	"16": 0.0625,
+	"32": 0.03125,
+	"64": 0.015625,
+	"128": 0.0078125,
+};
+
+export type GradualChange = {
+	resetXmlNoteIndex: number;
+	startXmlNoteIndex: number;
+	endXmlNoteIndex: number;
+	startWord: string;
+	startMeasureListIndex: number;
+	endMeasureListIndex: number;
+	resetMeasureListIndex: number;
+};
+
+export const speedInfo: { [key in string]: number } = {
+	"rall.": 1.333333333,
+	"poco rit.": 1.333333333,
+	"rit.": 1.333333333,
+	"molto rit.": 1.333333333,
+	"molto rall": 1.333333333,
+	molto: 1.333333333,
+	lentando: 1.333333333,
+	allargando: 1.333333333,
+	morendo: 1.333333333,
+	"accel.": 0.8,
+	calando: 2,
+	"poco accel.": 0.8,
+	"gradually slowing": 1.333333333,
+	slowing: 1.333333333,
+	slow: 1.333333333,
+	slowly: 1.333333333,
+	faster: 1.333333333,
+};
+
+/**
+ * 计算渐变速度
+ */
+export const calcGradual = () => {};
+
+/**
+ * 2022年9月14日版本 计算渐变速度,此方法不兼容之前的选择范围。
+ */
+export const calcGradual2 = () => {};
+
+/**
+ * 获取指定元素下一个Note元素
+ * @param ele 指定元素
+ * @param selectors 选择器
+ */
+const getNextNote = (ele: Element, selectors: string) => {
+	let index = 0;
+	const parentEle = ele.closest(selectors);
+	let pointer = parentEle;
+	const measure = parentEle?.closest("measure");
+	let siblingNote: Element | null | undefined = null;
+	// 查找到相邻的第一个note元素
+	while (!siblingNote && index < (measure?.childNodes.length || 50)) {
+		index++;
+		if (pointer?.nextElementSibling?.tagName === "note") {
+			siblingNote = pointer?.nextElementSibling;
+		}
+		pointer = pointer?.nextElementSibling!;
+	}
+	return siblingNote;
+};
+
+export type GradualElement = {
+	ele: Element;
+	index: number;
+	noteInMeasureIndex: number;
+	textContent: string;
+	measureIndex: number;
+	type: "words" | "metronome";
+	allDuration: number;
+	leftDuration: number;
+};
+
+export type GradualNote = GradualItem[];
+
+export type GradualItem = {
+	start: number;
+	measureIndex: number;
+	noteInMeasureIndex: number;
+	allDuration: number;
+	leftDuration: number;
+	type: string;
+	closedMeasureIndex: number;
+};
+
+// export type GradualItem = {
+//   start: number
+//   startMeasureIndex: number
+//   startNoteInMeasureIndex: number
+//   allDuration: number
+//   leftDuration: number
+//   endNoteInMeasureIndex?: number
+//   endMeasureIndex?: number
+//   end?: number
+// }
+
+/**
+ * 按照xml进行减慢速度的计算
+ * @param xml 始终按照第一分谱进行减慢速度的计算
+ */
+export const getGradualLengthByXml = (xml: string) => {
+	// const firstPartXml = onlyVisible(xml, 0)
+	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+	const measures = Array.from(xmlParse.querySelectorAll("measure"));
+	const notes = Array.from(xmlParse.querySelectorAll("note"));
+	const words = Array.from(xmlParse.querySelectorAll("words"));
+	const metronomes = Array.from(xmlParse.querySelectorAll("metronome"));
+
+	const eles: GradualElement[] = [];
+
+	for (const ele of [...words, ...metronomes]) {
+		const note = getNextNote(ele, "direction");
+		// console.log(ele, note)
+		if (note) {
+			const measure = note?.closest("measure")!;
+			const measureNotes = Array.from(measure.querySelectorAll("note"));
+
+			const noteInMeasureIndex = Array.from(measure.childNodes)
+				.filter((item) => item.nodeName === "note")
+				.findIndex((item) => item === note);
+
+			let allDuration = 0;
+			let leftDuration = 0;
+			for (let i = 0; i < measureNotes.length; i++) {
+				const n = measureNotes[i];
+				const duration = +(n.querySelector("duration")?.textContent || "0");
+				allDuration += duration;
+				if (i < noteInMeasureIndex) {
+					leftDuration = allDuration;
+				}
+			}
+			eles.push({
+				ele,
+				index: notes.indexOf(note!),
+				noteInMeasureIndex,
+				textContent: ele.textContent!,
+				measureIndex: measures.indexOf(measure!),
+				type: ele.tagName as GradualElement["type"],
+				allDuration,
+				leftDuration,
+			});
+		}
+	}
+
+	// 结尾处手动插入一个音符节点
+	eles.push({
+		ele: notes[notes.length - 1],
+		index: notes.length,
+		noteInMeasureIndex: 0,
+		textContent: "",
+		type: "metronome",
+		allDuration: 1,
+		leftDuration: 1,
+		measureIndex: measures.length,
+	});
+
+	const gradualNotes: GradualNote[] = [];
+	eles.sort((a, b) => a.index - b.index);
+	const keys = Object.keys(speedInfo).map((w) => w.toLocaleLowerCase());
+	for (const ele of eles) {
+		// 是否是同时也是关闭标签
+		let isLastNoteAndNotClosed = false;
+		let closed = 0;
+		const textContent = ele.textContent?.toLocaleLowerCase().trim();
+		if (ele === eles[eles.length - 1]) {
+			if (gradualNotes[gradualNotes.length - 1]?.length === 1) {
+				isLastNoteAndNotClosed = true;
+			}
+		}
+		const isKeyWork = keys.find((k) => {
+			const ks = k.split(" ");
+			return textContent && ks.includes(textContent);
+		});
+		if (ele.type === "metronome" || (ele.type === "words" && (textContent.startsWith("a tempo") || isKeyWork)) || isLastNoteAndNotClosed) {
+			const indexOf = gradualNotes.findIndex((item) => item.length === 1);
+			if (indexOf > -1 && ele.index > gradualNotes[indexOf]?.[0].start) {
+				closed = -1;
+				gradualNotes[indexOf][1] = {
+					start: ele.index,
+					measureIndex: ele.measureIndex,
+					closedMeasureIndex: ele.measureIndex,
+					noteInMeasureIndex: ele.noteInMeasureIndex,
+					allDuration: ele.allDuration,
+					leftDuration: ele.leftDuration,
+					type: textContent,
+				};
+			}
+		}
+		if (ele.type === "words" && isKeyWork) {
+			gradualNotes.push([
+				{
+					start: ele.index,
+					measureIndex: ele.measureIndex,
+					closedMeasureIndex: ele.measureIndex + closed,
+					noteInMeasureIndex: ele.noteInMeasureIndex,
+					allDuration: ele.allDuration,
+					leftDuration: ele.leftDuration,
+					type: textContent,
+				},
+			]);
+		}
+	}
+	return gradualNotes;
+};
+
+export const getGradualLength = (gradualChange: GradualChange, speed: number, osdm: OpenSheetMusicDisplay) => {
+	const { startMeasureListIndex, endMeasureListIndex, endXmlNoteIndex, startWord } = gradualChange;
+	const measures: SourceMeasure[] = [];
+	for (let index = startMeasureListIndex; index <= endMeasureListIndex; index++) {
+		const measure = osdm.Sheet.SourceMeasures[index];
+		measures.push(measure);
+	}
+	const allNoteDurations: number[] = [];
+	for (const measure of measures) {
+		if (allNoteDurations.length >= endXmlNoteIndex) {
+			break;
+		}
+		// @ts-ignore
+		measure.VerticalMeasureList[0]?.vfVoices["1"]?.tickables?.forEach((item) =>
+			allNoteDurations.push(noteDuration[item.duration as keyof typeof noteDuration])
+		);
+	}
+	const minDuration = Math.min(...allNoteDurations);
+	const parts = allNoteDurations.map((item) => item / minDuration);
+	const allParts = parts.reduce((total, val) => val + total, 0);
+	// const startMeasure = osdm.Sheet.SourceMeasures[startMeasureListIndex]
+	// const endMeasure = osdm.Sheet.SourceMeasures[endMeasureListIndex]
+	let surplusSpeed = speed / speedInfo[startWord?.toLocaleLowerCase()] || 1;
+	const diffSpeed = speed - surplusSpeed;
+	let useSpeed = 0;
+	const speeds: number[] = parts.map((item) => {
+		const s = ((diffSpeed - useSpeed) * item) / allParts;
+		return s;
+	});
+	// 120 111.9 104.4 96.9
+	// 8.1 7.5 7.2 6.9
+	// 0.6 0.3 0.3
+	const lingerSpeed: number[] = [];
+	for (let index = 0; index < speeds.length; index++) {
+		const s = speeds[index];
+		let beforeSpeed = 0;
+		let afterSpeed = 0;
+		for (let j = 0; j < index; j++) {
+			beforeSpeed += speeds[j];
+		}
+		afterSpeed += beforeSpeed;
+		afterSpeed += s;
+
+		lingerSpeed.push((afterSpeed + beforeSpeed) / 2);
+	}
+	// console.log(lingerSpeed, speeds[0], speeds, parts, allParts)
+	return lingerSpeed;
+};

+ 219 - 0
src/helpers/communication.ts

@@ -0,0 +1,219 @@
+import { storeData } from "../store";
+import {
+	CallBack,
+	IPostMessage,
+	listenerMessage,
+	postMessage,
+	promisefiyPostMessage,
+	removeListenerMessage,
+} from "../utils/native-message";
+/** 获取token */
+export const api_getToken = (): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "getToken" });
+};
+/**获取耳机的插入状态 */
+export const getEarphone = (): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "isWiredHeadsetOn" });
+};
+
+/** 获取异形屏信息 */
+export const isSpecialShapedScreen = (): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "isSpecialShapedScreen" });
+};
+
+/** 开始录音 */
+export const startSoundCheck = () => {
+	postMessage({
+		api: "startSoundCheck",
+	});
+};
+
+/** 录音返回 */
+export const sendResult = (callback: CallBack) => {
+	listenerMessage("sendResult", callback);
+};
+/** 取消监听录音返回 */
+export const removeResult = (callback: CallBack) => {
+	removeListenerMessage("sendResult", callback);
+};
+
+/** 结束录音 */
+export const endSoundCheck = () => {
+	postMessage({
+		api: "endSoundCheck",
+	});
+};
+
+/** 开始评测 */
+export const startEvaluating = (content: any): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "startEvaluating", content: content });
+};
+/** 结束评测 */
+export const endEvaluating = (content: any): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "endEvaluating", content: content });
+};
+/** 取消评测 */
+export const cancelEvaluating = () => {
+	postMessage({
+		api: "cancelEvaluating",
+	});
+};
+
+/** 评测开始录音 */
+export const api_startRecording = (): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "startRecording" });
+};
+/** 评测结束录音 */
+export const api_stopRecording = (): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "stopRecording" });
+};
+
+/** 和websocket通信 */
+export const api_proxyServiceMessage = (content: any): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "proxyServiceMessage", content });
+};
+/** 监听app真正开始录音 */
+export const api_recordStartTime = (callback: CallBack) => {
+	listenerMessage("recordStartTime", callback);
+};
+/** 卸载监听app真正开始录音 */
+export const api_remove_recordStartTime = (callback: CallBack) => {
+	removeListenerMessage("recordStartTime", callback);
+};
+
+/** 上传评测视频 */
+export const api_videoUpdate = (callback: CallBack) => {
+	postMessage(
+		{
+			api: "videoUpdate",
+		},
+		callback
+	);
+};
+
+/** 分享 */
+export const api_shareAchievements = (content: any): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "shareAchievements", content });
+};
+
+/** openwebview */
+export const api_openWebView = (content: any): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "openWebView", content });
+};
+
+/** 开启摄像头 */
+export const api_openCamera = (): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "openCamera" });
+};
+
+/** 关闭摄像头 */
+export const api_closeCamera = (): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "closeCamera" });
+};
+
+/** 安卓隐藏状态栏 */
+export const api_setStatusBarVisibility = () => {
+	// 安卓的状态栏
+	postMessage({
+		api: "setStatusBarVisibility",
+		content: {
+			isVisibility: 0,
+		},
+	});
+};
+
+/** 跟练录音切换 */
+export const api_cloudToggleFollow = (state: "start" | "end") => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({
+		api: "cloudToggleFollow",
+		content: {
+			state,
+		},
+	});
+};
+
+/** 跟练录音监听 */
+export const api_cloudFollowTime = (onFollowTime: CallBack, listen = true) => {
+	if (listen) {
+		listenerMessage("cloudFollowTime", onFollowTime);
+	} else {
+		removeListenerMessage("cloudFollowTime", onFollowTime);
+	}
+};
+
+/** 结束webview */
+export const api_back = () => {
+	postMessage({
+		api: "back",
+	});
+};
+/** 切换全屏loading */
+export const api_cloudLoading = (show = false) => {
+	postMessage({
+		api: "cloudLoading",
+		content: {
+			show,
+			type: "fullscreen",
+		},
+	});
+};
+
+/** 销毁云教练 */
+export const api_cloudDestroy = () => {
+	postMessage({
+		api: "cloudDestroy",
+	});
+};
+/** 事件埋点统计: 酷乐秀用,其它没有用 */
+export const api_setEventTracking = () => {
+	postMessage({
+		api: "setEventTracking",
+		content: {
+			type: "klx_xiaokuAI",
+		},
+	});
+};
+/** 保存图片 */
+export const api_savePicture = (content: any): Promise<IPostMessage | undefined> => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "savePicture", content });
+};
+/** 缓存评测分数 */
+export const api_setCache = (content: any) => {
+	postMessage({
+		api: "setCache",
+		content,
+	});
+};
+
+/** app切换到后台 */
+export const api_suspendPlay = (callback: CallBack) => {
+	listenerMessage("suspendPlay", callback);
+};
+
+/** 开始录制视频 */
+export const api_startCapture = () => {
+	postMessage({
+		api: "startCapture",
+	});
+};
+
+/** 结束录制视频 */
+export const api_endCapture = () => {
+	postMessage({
+		api: "endCapture",
+	});
+};

+ 12 - 0
src/helpers/eventemitter.ts

@@ -0,0 +1,12 @@
+import eventemitter from 'eventemitter3'
+
+const _event = new eventemitter()
+
+export enum EventEnum {
+    /** 评测结果返回 */
+    sendResultScore = 'sendResultScore',
+    /** 播放器播放到后面自动结束 */
+    playEnd = 'playEnd',
+}
+
+export default _event

+ 1025 - 0
src/helpers/formateMusic.ts

@@ -0,0 +1,1025 @@
+import dayjs from "dayjs";
+import duration from "dayjs/plugin/duration";
+import state, { customData } from "/src/state";
+import { browser } from "../utils/index";
+import {
+	isSpecialMark,
+	isSpeedKeyword,
+	Fraction,
+	SourceMeasure,
+	isGradientWords,
+	GRADIENT_SPEED_RESET_TAG,
+	StringUtil,
+	OpenSheetMusicDisplay,
+} from "/osmd-extended/src";
+import { GradualChange, speedInfo } from "./calcSpeed";
+const browserInfo = browser();
+dayjs.extend(duration);
+
+/**
+ * 获取节拍器的时间
+ * @param speed 速度
+ * @param firstMeasure 曲谱第一个小节
+ * @returns 节拍器的时间
+ */
+export const getFixTime = (speed: number) => {
+	const duration: any = getDuration(state.osmd as unknown as OpenSheetMusicDisplay);
+	let numerator = duration.numerator || 0;
+	let denominator = duration.denominator || 4;
+	const beatUnit = duration.beatUnit || "quarter";
+	if (state.repeatedBeats) {
+		// 音频制作问题仅2拍不重复
+		numerator = numerator === 2 ? 4 : numerator;
+	} else if (numerator === 2 && denominator === 4) {
+		numerator = 4
+	}
+	// console.log('diff', speed, duration, formatBeatUnit(beatUnit), denominator, numerator, (numerator / denominator))
+	return state.isOpenMetronome ? (60 / speed) * formatBeatUnit(beatUnit) * (numerator / denominator) : 0;
+};
+
+export const retain = (time: number) => {
+	return Math.ceil(time * 1000000) / 1000000;
+};
+
+export const formatLyricsEntries = (note: any) => {
+	const voiceEntries = note.parentStaffEntry?.voiceEntries || [];
+	const lyricsEntries: string[] = [];
+
+	for (const voic of voiceEntries) {
+		if (voic.lyricsEntries?.table) {
+			const values: any[] = Object.values(voic.lyricsEntries.table);
+			for (const lyric of values) {
+				lyricsEntries.push(lyric?.value.text);
+			}
+		}
+	}
+	return lyricsEntries;
+};
+
+export const getMeasureDurationDiff = (measure: any) => {
+	const { realValue: SRealValue } = measure.activeTimeSignature;
+	const { realValue: RRealValue } = measure.duration;
+	return SRealValue - RRealValue;
+};
+
+/** 按照dorico的渐快渐慢生成对应的速度 */
+export const createSpeedInfo = (gradualChange: GradualChange | undefined, speed: number) => {
+	if (gradualChange && speedInfo[gradualChange.startWord?.toLocaleLowerCase()]) {
+		const notenum = Math.max(gradualChange.endXmlNoteIndex, 3);
+		const speeds: number[] = [];
+		const startSpeed = speed;
+		const endSpeed = speed / speedInfo[gradualChange.startWord?.toLocaleLowerCase()];
+
+		for (let index = 0; index < notenum; index++) {
+			const speed = startSpeed + ((endSpeed - startSpeed) / notenum) * (index + 1);
+			speeds.push(speed);
+		}
+		return speeds;
+	}
+	return;
+};
+
+const tranTime = (str: string = "") => {
+	let result = str;
+	const splits = str.split(":");
+	if (splits.length === 1) {
+		result = `00:${splits[0]}:00`;
+	} else if (splits.length === 2) {
+		result = `00:${splits[0]}:${splits[1]}`;
+	}
+	// console.log(`1970-01-01 00:${result}0`)
+	return `1970-01-01 00:${result}0`;
+};
+
+export const getSlursNote = (note: any, pos?: "start" | "end") => {
+	return pos === "end" ? note.noteElement.slurs[0]?.endNote : note.noteElement.slurs[0]?.startNote;
+};
+
+export const getNoteBySlursStart = (note: any, anyNoteHasSlurs?: boolean, pos?: "start" | "end") => {
+	let activeNote = note;
+	let slursNote = getSlursNote(activeNote, pos);
+
+	for (const item of activeNote.measures) {
+		if (item.noteElement.slurs.length) {
+			slursNote = getSlursNote(item, pos);
+			activeNote = item;
+		}
+	}
+	return activeNote;
+};
+
+/** 根据 noteElement 获取note */
+export const getParentNote = (note: any) => {
+	let parentNote;
+	if (note) {
+		// time = activeNote.time
+		for (const n of state.times) {
+			if (note === n.noteElement) {
+				// console.log(note)
+				return n;
+			}
+		}
+	}
+	return parentNote;
+};
+
+export type FractionDefault = {
+	numerator: number;
+	denominator: number;
+	wholeValue: number;
+};
+
+export type Duration = FractionDefault & {
+	TempoInBPM: number;
+	beatUnit: string;
+};
+
+export const getDuration = (osmd?: OpenSheetMusicDisplay): Duration => {
+	if (osmd) {
+		const { Duration, TempoInBPM, ActiveTimeSignature, TempoExpressions } = osmd.GraphicSheet.MeasureList[0][0]?.parentSourceMeasure;
+		if (Duration) {
+			let beatUnit = "quarter";
+			for (const item of TempoExpressions) {
+				beatUnit = item.InstantaneousTempo.beatUnit || "quarter";
+			}
+			const duration = formatDuration(ActiveTimeSignature, Duration) as unknown as FractionDefault;
+			return {
+				...duration,
+				TempoInBPM,
+				beatUnit,
+			};
+		}
+	}
+	const duration = new Fraction() as unknown as FractionDefault;
+	return {
+		...duration,
+		TempoInBPM: 90,
+		beatUnit: "quarter",
+	};
+};
+
+export function formatDuration(activeTimeSignature: Fraction, duration: Fraction): Fraction {
+	// 弱起第一小节duration不对
+	return activeTimeSignature;
+}
+
+export function formatBeatUnit(beatUnit: string) {
+	let multiple = 4;
+	switch (beatUnit) {
+		case "1024th":
+			// bpm = bpm;
+			multiple = 1024;
+			break;
+		case "512th":
+			// divisionsFromNote = (noteDuration / 4) * 512;
+			multiple = 512;
+			break;
+		case "256th":
+			// divisionsFromNote = (noteDuration / 4) * 256;
+			multiple = 256;
+			break;
+		case "128th":
+			// divisionsFromNote = (noteDuration / 4) * 128;
+			multiple = 128;
+			break;
+		case "64th":
+			// divisionsFromNote = (noteDuration / 4) * 64;
+			multiple = 64;
+			break;
+		case "32nd":
+			// divisionsFromNote = (noteDuration / 4) * 32;
+			multiple = 32;
+			break;
+		case "16th":
+			// divisionsFromNote = (noteDuration / 4) * 16;
+			multiple = 16;
+			break;
+		case "eighth":
+			// divisionsFromNote = (noteDuration / 4) * 8;
+			multiple = 8;
+			break;
+		case "quarter":
+			multiple = 4;
+			break;
+		case "half":
+			// divisionsFromNote = (noteDuration / 4) * 2;
+			multiple = 2;
+			break;
+		case "whole":
+			// divisionsFromNote = (noteDuration / 4);
+			multiple = 1;
+			break;
+		case "breve":
+			// divisionsFromNote = (noteDuration / 4) / 2;
+			multiple = 0.5;
+			break;
+		case "long":
+			// divisionsFromNote = (noteDuration / 4) / 4;
+			multiple = 0.25;
+			break;
+		case "maxima":
+			// divisionsFromNote = (noteDuration / 4) / 8;
+			multiple = 0.125;
+			break;
+		default:
+			break;
+	}
+
+	return multiple;
+}
+
+/** 根据音符单位,速度,几几拍计算正确的时间 */
+export function getTimeByBeatUnit(beatUnit: string, bpm: number, denominator: number) {
+	return (denominator / formatBeatUnit(beatUnit)) * bpm;
+}
+
+export type CustomInfo = {
+	showSpeed: boolean;
+	parsedXML: string;
+};
+
+/** 从xml中获取自定义信息,并删除多余的字符串 */
+export const getCustomInfo = (xml: string): CustomInfo => {
+	const data = {
+		showSpeed: true,
+		parsedXML: xml,
+	};
+	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+	const words: any = xmlParse.getElementsByTagName("words");
+	for (const word of words) {
+		if (word && word.textContent?.trim() === "隐藏速度") {
+			data.showSpeed = false;
+			word.textContent = "";
+		}
+		if (word && word.textContent?.trim() === "@") {
+			word.textContent = "segno";
+		}
+	}
+	data.parsedXML = new XMLSerializer().serializeToString(xmlParse);
+	return data;
+};
+
+/**
+ * 替换文本标签中的内容
+ */
+const replaceTextConent = (beforeText: string, afterText: string, ele: Element): Element => {
+	const words: any = ele?.getElementsByTagName("words");
+	for (const word of words) {
+		if (word && word.textContent?.trim() === beforeText) {
+			word.textContent = afterText;
+		}
+	}
+	return ele;
+};
+
+/**
+ * 添加第一分谱信息至当前分谱
+ * @param ele 需要插入的元素
+ * @param fitstParent 合奏谱第一个分谱
+ * @param parent 需要添加的分谱
+ */
+const setElementNoteBefore = (ele: Element, fitstParent: Element, parent?: Element | null) => {
+	let noteIndex: number = 0;
+	if (!fitstParent) {
+		return;
+	}
+	for (let index = 0; index < fitstParent.childNodes.length; index++) {
+		const element = fitstParent.childNodes[index];
+		if (element.nodeName === "note") {
+			noteIndex++;
+		}
+		if (element === ele) {
+			break;
+		}
+	}
+	if (noteIndex === 0 && parent) {
+		parent.insertBefore(ele, parent.childNodes[0]);
+		return;
+	}
+	if (parent && parent.childNodes.length > 0) {
+		let noteIndex2: number = 0;
+		const notes = Array.from(parent.childNodes).filter((child) => child.nodeName === "note");
+		const lastNote = notes[notes.length - 1];
+		if (noteIndex >= notes.length && lastNote) {
+			parent.insertBefore(ele, parent.childNodes[Array.from(parent.childNodes).indexOf(lastNote)]);
+			return;
+		}
+		for (let index = 0; index < notes.length; index++) {
+			const element = notes[index];
+			if (element.nodeName === "note") {
+				noteIndex2 = noteIndex2 + 1;
+				if (noteIndex2 === noteIndex) {
+					parent.insertBefore(ele, element);
+					break;
+				}
+			}
+		}
+	}
+	// console.log(noteIndex, parent)
+};
+
+/**
+ * 检查传入文字是否为重复关键词
+ * @param text 总谱xml
+ * @returns 是否是重复关键词
+ */
+export const isRepeatWord = (text: string): boolean => {
+	if (text) {
+		const innerText = text.toLocaleLowerCase();
+		const dsRegEx: string = "d\\s?\\.s\\.";
+		const dcRegEx: string = "d\\.\\s?c\\.";
+
+		return (
+			innerText === "@" ||
+			StringUtil.StringContainsSeparatedWord(innerText, dsRegEx + " al fine", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, dsRegEx + " al coda", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, dcRegEx + " al fine", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, dcRegEx + " al coda", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, dcRegEx) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "da\\s?capo", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, dsRegEx, true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "dal\\s?segno", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "al\\s?coda", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "to\\s?coda", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "a (la )?coda", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "fine", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "coda", true) ||
+			StringUtil.StringContainsSeparatedWord(innerText, "segno", true)
+		);
+	}
+	return false;
+};
+
+export const onlyVisible = (xml: string, partIndex: number): string => {
+	if (!xml) return "";
+	const detailId = state.examSongId + "";
+	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+	const partList = xmlParse.getElementsByTagName("part-list")?.[0]?.getElementsByTagName("score-part") || [];
+	const partListNames = Array.from(partList).map((item) => item.getElementsByTagName("part-name")?.[0].textContent || "");
+	const parts: any = xmlParse.getElementsByTagName("part");
+	// const firstTimeInfo = parts[0]?.getElementsByTagName('metronome')[0]?.parentElement?.parentElement?.cloneNode(true)
+	const firstMeasures = [...parts[0]?.getElementsByTagName("measure")];
+	const metronomes = [...parts[0]?.getElementsByTagName("metronome")];
+	const words = [...parts[0]?.getElementsByTagName("words")];
+	const codas = [...parts[0]?.getElementsByTagName("coda")];
+	const rehearsals = [...parts[0]?.getElementsByTagName("rehearsal")];
+
+	/** 第一分谱如果是约定的配置分谱则跳过 */
+	if (partListNames[0]?.toLocaleUpperCase?.() === "COMMON") {
+		partIndex++;
+		partListNames.shift();
+	}
+	const visiblePartInfo = partList[partIndex];
+	// console.log(visiblePartInfo, partIndex)
+	state.partListNames = partListNames;
+	if (visiblePartInfo) {
+		const id = visiblePartInfo.getAttribute("id");
+		Array.from(parts).forEach((part: any) => {
+			if (part && part.getAttribute("id") !== id) {
+				part.parentNode?.removeChild(part);
+				// 不等于第一行才添加避免重复添加
+			} else if (part && part.getAttribute("id") !== "P1") {
+				// 速度标记仅保留最后一个
+				const metronomeData: {
+					[key in string]: Element;
+				} = {};
+				for (let i = 0; i < metronomes.length; i++) {
+					const metronome = metronomes[i];
+					const metronomeContainer = metronome.parentElement?.parentElement?.parentElement;
+					if (metronomeContainer) {
+						const index = firstMeasures.indexOf(metronomeContainer);
+						metronomeData[index] = metronome;
+					}
+				}
+				Object.values(metronomeData).forEach((metronome) => {
+					const metronomeContainer: any = metronome.parentElement?.parentElement;
+					const parentMeasure: any = metronomeContainer?.parentElement;
+					const measureMetronomes = [...(parentMeasure?.childNodes || [])];
+					const metronomesIndex = metronomeContainer ? measureMetronomes.indexOf(metronomeContainer) : -1;
+					// console.log(parentMeasure)
+					if (parentMeasure && metronomesIndex > -1) {
+						const index = firstMeasures.indexOf(parentMeasure);
+						const activeMeasure = part.getElementsByTagName("measure")[index];
+						setElementNoteBefore(metronomeContainer, parentMeasure, activeMeasure);
+					}
+				});
+				/** word比较特殊需要精确到note位置 */
+				words.forEach((word) => {
+					let text = word.textContent || "";
+					text = ["cresc."].includes(text) ? "" : text;
+					if ((isSpecialMark(text) || isSpeedKeyword(text) || isGradientWords(text) || isRepeatWord(text) || GRADIENT_SPEED_RESET_TAG) && text) {
+						const wordContainer = word.parentElement?.parentElement;
+						const parentMeasure = wordContainer?.parentElement;
+						const measureWords = [...(parentMeasure?.childNodes || [])];
+						const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1;
+						if (wordContainer && parentMeasure && wordIndex > -1) {
+							const index = firstMeasures.indexOf(parentMeasure);
+							const activeMeasure = part.getElementsByTagName("measure")[index];
+							// 找当前小节是否包含word标签
+							const _words = Array.from(activeMeasure?.getElementsByTagName("words") || []);
+							// 遍历word标签,检查是否和第一小节重复,如果有重复则不平移word
+							const total = _words.reduce((total: any, _word: any) => {
+								if (_word.textContent?.includes(text)) {
+									total++;
+								}
+								return total;
+							}, 0);
+							if (total === 0) {
+								if (["12280"].includes(detailId)) {
+									activeMeasure?.insertBefore(wordContainer.cloneNode(true), activeMeasure?.childNodes[wordIndex]);
+								} else {
+									setElementNoteBefore(wordContainer, parentMeasure, activeMeasure);
+								}
+							}
+						}
+					}
+				});
+				/** word比较特殊需要精确到note位置 */
+				codas.forEach((coda) => {
+					const wordContainer = coda.parentElement?.parentElement;
+					const parentMeasure = wordContainer?.parentElement;
+					const measureWords = [...(parentMeasure?.childNodes || [])];
+					const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1;
+					if (wordContainer && parentMeasure && wordIndex > -1) {
+						const index = firstMeasures.indexOf(parentMeasure);
+						const activeMeasure = part.getElementsByTagName("measure")[index];
+						if (["12280"].includes(detailId)) {
+							activeMeasure?.insertBefore(wordContainer.cloneNode(true), activeMeasure?.childNodes[wordIndex]);
+						} else {
+							setElementNoteBefore(wordContainer, parentMeasure, activeMeasure);
+						}
+					}
+				});
+				rehearsals.forEach((rehearsal) => {
+					const container = rehearsal.parentElement?.parentElement;
+					const parentMeasure = container?.parentElement;
+					// console.log(rehearsal)
+					if (parentMeasure) {
+						const index = firstMeasures.indexOf(parentMeasure);
+						part.getElementsByTagName("measure")[index]?.appendChild(container.cloneNode(true));
+						// console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
+					}
+				});
+			} else {
+				words.forEach((word) => {
+					const text = word.textContent || "";
+					if (isSpeedKeyword(text) && text) {
+						const wordContainer = word.parentElement?.parentElement?.parentElement;
+						if (wordContainer && wordContainer.firstElementChild && wordContainer.firstElementChild !== word) {
+							const wordParent = word.parentElement?.parentElement;
+							const fisrt = wordContainer.firstElementChild;
+							wordContainer.insertBefore(wordParent, fisrt);
+						}
+					}
+				});
+			}
+
+			// 最后一个小节的结束线元素不在最后 调整
+			if (part && part.getAttribute("id") === id) {
+				const barlines = part.getElementsByTagName("barline");
+				const lastParent = barlines[barlines.length - 1]?.parentElement;
+				if (lastParent?.lastElementChild?.tagName !== "barline") {
+					const children = lastParent?.children || [];
+					for (let el of children) {
+						if (el.tagName === "barline") {
+							// 将结束线元素放到最后
+							lastParent?.appendChild(el);
+							break;
+						}
+					}
+				}
+			}
+		});
+		Array.from(partList).forEach((part) => {
+			if (part && part.getAttribute("id") !== id) {
+				part.parentNode?.removeChild(part);
+			}
+		});
+	}
+	// console.log(xmlParse)
+	return new XMLSerializer().serializeToString(appoggianceFormate(xmlParse));
+};
+
+// 倚音后连音线
+export const appoggianceFormate = (xmlParse: Document): Document => {
+	if (!xmlParse) return xmlParse;
+	const graces: any = xmlParse.querySelectorAll("grace");
+	if (!graces.length) return xmlParse;
+	const getNextElement = (el: HTMLElement): HTMLElement => {
+		if (el.querySelector("grace")) {
+			return getNextElement(el?.nextElementSibling as HTMLElement);
+		}
+		return el;
+	};
+	for (let grace of graces) {
+		const notations = grace.parentElement?.querySelector("notations");
+		if (notations && notations.querySelectorAll("slur").length > 1) {
+			let nextEle: Element = getNextElement(grace.parentElement?.nextElementSibling as HTMLElement);
+			if (nextEle && nextEle.querySelectorAll("slur").length > 0) {
+				const slurNumber = Array.from(nextEle.querySelector("notations")?.children || []).map((el: Element) => {
+					return el.getAttribute("number");
+				});
+				const slurs = notations.querySelectorAll("slur");
+				for (let nota of slurs) {
+					if (!slurNumber.includes(nota.getAttribute("number"))) {
+						nextEle.querySelector("notations")?.appendChild(nota);
+					}
+				}
+			}
+		}
+	}
+	return xmlParse;
+};
+
+/** 根据ID获取最顶级ID */
+export const isWithinScope = (tree: any[], id: number): number => {
+	if (!tree) return 0;
+	let result = 0;
+	for (const item of tree) {
+		if (item.id === id) {
+			result = item.id;
+			break;
+		}
+		if (item.sysMusicScoreCategoriesList) {
+			result = isWithinScope(item.sysMusicScoreCategoriesList, id);
+			if (result > 0) {
+				result = item.id;
+			}
+			if (result) break;
+		}
+	}
+	return result;
+};
+
+class NoteList {
+	notes: any[] = [];
+	constructor(notes: any[]) {
+		this.notes = notes;
+	}
+
+	public last() {
+		return this.notes[this.notes.length - 1];
+	}
+
+	public list() {
+		return this.notes;
+	}
+}
+
+export const getNotesByid = (id: string): NoteList => {
+	const notes = new NoteList(state.times.filter((item) => item.id === id));
+	return notes;
+};
+
+/** 格式化当前曲谱缩放比例 */
+export const formatZoom = (num = 1) => {
+	return num * state.zoom;
+};
+
+/** 格式化曲谱
+ * 1.全休止符的小节,没有音符默认加个全休止符
+ */
+export const formatXML = (xml: string): string => {
+	if (!xml) return "";
+	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+	const measures = Array.from(xmlParse.getElementsByTagName("measure"));
+	// let speed = -1
+	let beats = -1;
+	let beatType = -1;
+	// 小节中如果没有节点默认为休止符
+	for (const measure of measures) {
+		if (beats === -1 && measure.getElementsByTagName("beats").length) {
+			beats = parseInt(measure.getElementsByTagName("beats")[0].textContent || "4");
+		}
+		if (beatType === -1 && measure.getElementsByTagName("beat-type").length) {
+			beatType = parseInt(measure.getElementsByTagName("beat-type")[0].textContent || "4");
+		}
+		// if (speed === -1 && measure.getElementsByTagName('per-minute').length) {
+		//   speed = parseInt(measure.getElementsByTagName('per-minute')[0].textContent || this.firstLib?.speed)
+		// }
+		const divisions = parseInt(measure.getElementsByTagName("divisions")[0]?.textContent || "256");
+		if (measure.getElementsByTagName("note").length === 0) {
+			const forwardTimeElement = measure.getElementsByTagName("forward")[0]?.getElementsByTagName("duration")[0];
+			if (forwardTimeElement) {
+				forwardTimeElement.textContent = "0";
+			}
+			measure.innerHTML =
+				measure.innerHTML +
+				`
+        <note>
+          <rest measure="yes"/>
+          <duration>${divisions * beats}</duration>
+          <voice>1</voice>
+          <type>whole</type>
+        </note>`;
+		}
+	}
+	return new XMLSerializer().serializeToString(xmlParse);
+};
+
+/** 获取所有音符的时值,以及格式化音符 */
+export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
+	const customNoteRealValue = customData.customNoteRealValue;
+	const customNoteCurrentTime = customData.customNoteCurrentTime;
+	const detailId = state.examSongId + "";
+	const partIndex = state.partIndex + "";
+	let fixtime = browserInfo.huawei ? 0.08 : 0; //getFixTime()
+	const allNotes: any[] = [];
+	const allNoteId: string[] = [];
+	const allMeasures: any[] = [];
+	const { originSpeed: baseSpeed } = state;
+	const formatRealKey = (realKey: number, detail: any) => {
+		// 不是管乐迷, 不处理
+		if (state.appName !== "GYM") return realKey;
+		// 长笛的LEVEL 2-5-1条练习是泛音练习,以每小节第一个音的指法为准,高音不变变指法。
+		const olnyOneIds = ["906"];
+		if (olnyOneIds.includes(detailId)) {
+			return detail.measures[0]?.realKey || realKey;
+		}
+		// 圆号的LEVEL 2-5条练习是泛音练习,最后四小节指法以连音线第一个小节为准
+		const olnyOneIds2 = ["782", "784"];
+		if (olnyOneIds2.includes(detailId)) {
+			const measureNumbers = [14, 16, 30, 32];
+			if (measureNumbers.includes(detail.firstVerticalMeasure?.measureNumber)) {
+				return allNotes[allNotes.length - 1]?.realKey || realKey;
+			}
+		}
+		// 2-6 第三小节指法按照第一个音符显示
+		const filterIds = ["900", "901", "640", "641", "739", "740", "800", "801", "773", "774", "869", "872", "714", "715"];
+		if (filterIds.includes(detailId)) {
+			if (detail.firstVerticalMeasure?.measureNumber === 3 || detail.firstVerticalMeasure?.measureNumber === 9) {
+				return detail.measures[0]?.realKey || realKey;
+			}
+		}
+		return realKey;
+	};
+	if (!osmd.cursor) return [];
+	const iterator: any = osmd.cursor.Iterator;
+	// console.log("🚀 ~ iterator:", iterator)
+	console.time("音符跑完时间");
+
+	let i = 0;
+	let si = 0;
+	let measures: any[] = [];
+	let stepSpeeds: number[] = [];
+	/** 弱起时间 */
+	let difftime = 0;
+	let usetime = 0;
+	let relaMeasureLength = 0;
+	let beatUnit = "quarter";
+	let gradualSpeed;
+	let gradualChange: GradualChange | undefined;
+	let gradualChangeIndex = 0;
+	let totalMultipleRestMeasures = 0;
+	let multipleRestMeasures = 0;
+	const _notes = [] as any[];
+	if (state.gradualTimes) {
+		console.log("后台设置的渐慢小节时间", state.gradual, state.gradualTimes);
+	}
+
+	let currentTimeStamp = iterator.currentTimeStamp.RealValue;
+	const currentTimes = [] as any[];
+	let isSetNextNoteReal = false;
+	let differFrom = 0;
+	while (!iterator.EndReached) {
+		// console.log({ ...iterator });
+		const voiceEntries = iterator.CurrentVoiceEntries?.[0] ? [iterator.CurrentVoiceEntries?.[0]] : [];
+		let currentVoiceEntries: any[] = [];
+		// 单声部多声轨
+		if (state.multitrack > 0) {
+			currentVoiceEntries = [...iterator.CurrentVoiceEntries];
+		} else {
+			currentVoiceEntries = [...iterator.CurrentVoiceEntries].filter((n) => {
+				return n && n?.ParentVoice?.VoiceId != 1;
+			});
+		}
+		let currentTime = 0;
+		let isDouble = false;
+		let isMutileSubject = false;
+
+		if (currentVoiceEntries.length && !isSetNextNoteReal) {
+			isDouble = true;
+			let voiceNotes = [...iterator.CurrentVoiceEntries].reduce((notes, n) => {
+				notes.push(...n.Notes);
+				return notes;
+			}, [] as any);
+			voiceNotes = voiceNotes.sort((a: any, b: any) => a?.length?.realValue - b?.length?.realValue);
+			currentTime = voiceNotes?.[0]?.length?.realValue || 0;
+
+			if (state.multitrack > 0 && currentVoiceEntries.length === 2) {
+				const min = voiceNotes[0]?.length?.realValue || 0;
+				const max = voiceNotes[voiceNotes.length - 1]?.length?.realValue || 0;
+				differFrom = max - min;
+				isSetNextNoteReal = differFrom === 0 ? false : true;
+			}
+		}
+		// 多声部上下音符没对齐,光标多走一拍
+		if (_notes[_notes.length - 1]?.isDouble && !currentVoiceEntries.length) {
+			isMutileSubject = true;
+		}
+		if (state.multitrack > 0 && !isDouble && isSetNextNoteReal) {
+			isDouble = true;
+			currentTime = differFrom;
+			isSetNextNoteReal = false;
+			differFrom = 0;
+		}
+		currentTimes.push(iterator.currentTimeStamp.realValue - currentTimeStamp);
+		currentTimeStamp = iterator.currentTimeStamp.realValue;
+		for (const v of voiceEntries) {
+			let note = v.notes[0];
+			if (note.IsGraceNote) {
+				// 如果是装饰音, 取不是装饰音的时值
+				const voice = note.parentStaffEntry.voiceEntries.find((_v: any) => !_v.isGrace);
+				note = voice.notes[0];
+			}
+			note.fixedKey = note.ParentVoiceEntry.ParentVoice.Parent.SubInstruments[0].fixedKey || 0;
+			// 有倚音
+			if (note?.voiceEntry?.isGrace) {
+				isDouble = true;
+				let ns = [...iterator.currentVoiceEntries].reduce((notes, n) => {
+					notes.push(...n.notes);
+					return notes;
+				}, []);
+				ns = ns.sort((a: any, b: any) => b?.length?.realValue - a?.length?.realValue);
+				currentTime = currentTime != 0 ? Math.min(ns?.[0]?.length?.realValue, currentTime) : ns?.[0]?.length?.realValue;
+			}
+			if (state.multitrack > 0 && currentTime > note.length.realValue) {
+				currentTime = note.length.realValue;
+			}
+			_notes.push({
+				note,
+				iterator: { ...iterator },
+				currentTime,
+				isDouble,
+				isMutileSubject,
+			});
+		}
+
+		iterator.moveToNextVisibleVoiceEntry(false);
+	}
+	for (let { note, iterator, currentTime, isDouble, isMutileSubject } of _notes) {
+		if (note) {
+			if (si === 0) {
+				allMeasures.push(note.sourceMeasure);
+			}
+			if (si === 0 && state.isSpecialBookCategory) {
+				for (const expression of (note.sourceMeasure as SourceMeasure)?.TempoExpressions) {
+					if (expression?.InstantaneousTempo?.beatUnit) {
+						// 取最后一个有效的tempo
+						beatUnit = expression.InstantaneousTempo.beatUnit;
+					}
+				}
+			}
+			let measureSpeed = note.sourceMeasure.tempoInBPM;
+			const { metronomeNoteIndex } = iterator.currentMeasure;
+			if (metronomeNoteIndex !== 0 && metronomeNoteIndex > si) {
+				measureSpeed = allNotes[allNotes.length - 1]?.speed || 100;
+			}
+
+			const activeVerticalMeasureList = [note.sourceMeasure.verticalMeasureList?.[0]] || [];
+			const { realValue } = iterator.currentTimeStamp;
+			const { RealValue: vRealValue, Denominator: vDenominator } = formatDuration(
+				iterator.currentMeasure.activeTimeSignature,
+				iterator.currentMeasure.duration
+			);
+			let { wholeValue, numerator, denominator, realValue: NoteRealValue } = note.length;
+			if (customNoteRealValue[i]) {
+				// console.log(NoteRealValue, customNoteRealValue[i])
+				NoteRealValue = customNoteRealValue[i];
+			}
+			if (isDouble && currentTime > 0) {
+				if (currentTime != NoteRealValue) {
+					console.log(`小节 ${note.sourceMeasure.MeasureNumberXML} 替换: noteLength: ${NoteRealValue}, 最小: ${currentTime}`);
+					NoteRealValue = currentTime;
+				}
+			}
+			// note.sourceMeasure.MeasureNumberXML === 8 && console.error(`小节 ${note.sourceMeasure.MeasureNumberXML}`, NoteRealValue)
+			// 管乐迷,按自定义按读取到的音符时值
+			if (customNoteCurrentTime) {
+				if (isMutileSubject && currentTimes[i + 1] > 0 && NoteRealValue > currentTimes[i + 1]) {
+					console.log(NoteRealValue, currentTimes[i + 1])
+					NoteRealValue = currentTimes[i + 1];
+				}
+			}
+
+			let relativeTime = usetime;
+			// 速度不能为0 此处的速度应该是按照设置的速度而不是校准后的速度,否则mp3速度不对
+			let beatSpeed = (state.isSpecialBookCategory ? measureSpeed : baseSpeed) || 1;
+			// 如果有节拍器,需要将节拍器的时间算出来
+			if (i === 0) {
+				fixtime += getFixTime(beatSpeed);
+				state.fixtime = fixtime;
+				console.log("fixtime:", fixtime, '速度:', beatSpeed, "state.isSpecialBookCategory:", state.isSpecialBookCategory, 'state.isOpenMetronome:', state.isOpenMetronome);
+			}
+			// console.log(getTimeByBeatUnit(beatUnit, measureSpeed, iterator.currentMeasure.activeTimeSignature.Denominator))
+			let gradualLength = 0;
+			let speed = (state.isSpecialBookCategory ? measureSpeed : baseSpeed) || 1;
+			gradualChange = iterator.currentMeasure.speedInfo || gradualChange;
+			gradualSpeed = osmd.Sheet.SoundTempos?.get(note.sourceMeasure.measureListIndex) || gradualSpeed;
+			if (!gradualSpeed || gradualSpeed.length < 2) {
+				gradualSpeed = createSpeedInfo(gradualChange, speed);
+			}
+			// console.log({...iterator.currentMeasure},gradualChange, gradualSpeed)
+			const measureListIndex = iterator.currentMeasure.measureListIndex;
+			// 计算相差时间按照比例分配到所有音符上
+			if (state.gradualTimes && Object.keys(state.gradualTimes).length > 0) {
+				const withInRangeNote = state.gradual.find((item, index) => {
+					const nextItem: any = state.gradual[index + 1];
+					return (
+						item[0].measureIndex <= measureListIndex &&
+						item[1]?.measureIndex! >= measureListIndex &&
+						(!nextItem || nextItem?.[0].measureIndex !== measureListIndex)
+					);
+				});
+				const [first, last] = withInRangeNote || [];
+				if (first && last) {
+					// 小节数量
+					const continuous = last.measureIndex - first.measureIndex;
+					// 开始小节内
+					const inTheFirstMeasure = first.closedMeasureIndex == measureListIndex && si >= first.noteInMeasureIndex;
+					// 结束小节内
+					const inTheLastMeasure = last.closedMeasureIndex === measureListIndex && si < last.noteInMeasureIndex;
+					// 范围内小节
+					const inFiestOrLastMeasure = first.closedMeasureIndex !== measureListIndex && last.closedMeasureIndex !== measureListIndex;
+					if (inTheFirstMeasure || inTheLastMeasure || inFiestOrLastMeasure) {
+						const startTime = state.gradualTimes[first.measureIndex];
+						const endTime = state.gradualTimes[last.measureIndex];
+						if (startTime && endTime) {
+							const times = continuous - first.leftDuration / first.allDuration + last.leftDuration / last.allDuration;
+							const diff = dayjs(tranTime(endTime)).diff(dayjs(tranTime(startTime)), "millisecond");
+							gradualLength = ((NoteRealValue / vRealValue / times) * diff) / 1000;
+						}
+					}
+				}
+			} else if (state.appName === "GYM" && gradualChange && gradualSpeed && (gradualChange.startXmlNoteIndex === si || gradualChangeIndex > 0)) {
+				const startSpeed = gradualSpeed[0] - (gradualSpeed[1] - gradualSpeed[0]);
+				const { resetXmlNoteIndex, endXmlNoteIndex } = gradualChange;
+				const noteDiff = endXmlNoteIndex;
+				let stepSpeed = (gradualSpeed[gradualSpeed.length - 1] - startSpeed) / noteDiff;
+				stepSpeed = note.DotsXml ? stepSpeed / 1.5 : stepSpeed;
+				if (gradualChangeIndex < noteDiff) {
+					const tempSpeed = Math.ceil(speed + stepSpeed * gradualChangeIndex);
+					let tmpSpeed = getTimeByBeatUnit(beatUnit, tempSpeed, iterator.currentMeasure.activeTimeSignature.Denominator);
+					const maxLength = (wholeValue + numerator / denominator) * vDenominator * (60 / tmpSpeed);
+					// speed += stepSpeeds.reduce((a, b) => a + b, 0)
+					speed += Math.ceil(stepSpeed * (gradualChangeIndex + 1));
+					tmpSpeed = getTimeByBeatUnit(beatUnit, speed, iterator.currentMeasure.activeTimeSignature.Denominator);
+					const minLength = (wholeValue + numerator / denominator) * vDenominator * (60 / tmpSpeed);
+					gradualLength = (maxLength + minLength) / 2;
+				} else if (resetXmlNoteIndex > gradualChangeIndex) {
+					speed = allNotes[i - 1]?.speed;
+				}
+				beatSpeed =
+					(state.isSpecialBookCategory ? getTimeByBeatUnit(beatUnit, speed, iterator.currentMeasure.activeTimeSignature.Denominator) : baseSpeed) || 1;
+				const isEnd = !(gradualChangeIndex < noteDiff) && !(resetXmlNoteIndex > gradualChangeIndex);
+				gradualChangeIndex++;
+				if (isEnd) {
+					gradualChangeIndex = 0;
+					gradualChange = undefined;
+					gradualSpeed = undefined;
+					stepSpeeds = [];
+				}
+			}
+			const _noteLength = NoteRealValue;
+			let noteLength = gradualLength ? gradualLength : Math.min(vRealValue, NoteRealValue) * formatBeatUnit(beatUnit) * (60 / beatSpeed);
+			const measureLength = vRealValue * vDenominator * (60 / beatSpeed);
+			// console.table({value: iterator.currentTimeStamp.realValue, vRealValue,NoteRealValue, noteLength,measureLength, MeasureNumberXML: note.sourceMeasure.MeasureNumberXML})
+			// console.log(i, Math.min(vRealValue, NoteRealValue),noteLength,gradualLength, formatBeatUnit(beatUnit),beatSpeed, NoteRealValue * formatBeatUnit(beatUnit) * (60 / beatSpeed) )
+			usetime += noteLength;
+			relaMeasureLength += noteLength;
+			let relaEndtime = noteLength + relativeTime;
+			const fixedKey = note.fixedKey || 0;
+			const svgElement = activeVerticalMeasureList[0]?.vfVoices["1"]?.tickables[si];
+			// console.log(note.sourceMeasure.MeasureNumberXML,note,svgElement, NoteRealValue, measureLength)
+			if (allNotes.length && allNotes[allNotes.length - 1].relativeTime === relativeTime) {
+				continue;
+			}
+			// console.log(iterator.currentMeasure)
+			// 如果是弱起就补齐缺省的时长
+			if (i === 0) {
+				let _firstMeasureRealValue = 0;
+				const staffEntries = note.sourceMeasure.verticalMeasureList?.[0]?.staffEntries || [];
+				//计算第一个小节里面的音符时值是否等于整个小节的时值
+				staffEntries.forEach((_a: any) => {
+					if (_a?.sourceStaffEntry?.voiceEntries?.[0]?.notes?.[0]?.length?.realValue) {
+						_firstMeasureRealValue += _a.sourceStaffEntry.voiceEntries[0].notes[0].length.realValue;
+					}
+				});
+				if (_firstMeasureRealValue < vRealValue) {
+					// console.log(_firstMeasureRealValue, vRealValue)
+					// 如果是弱起,将整个小节的时值减去音符的时值,就是缺省的时值
+					difftime = measureLength - noteLength;
+				}
+				if (difftime > 0) {
+					fixtime += difftime;
+				}
+				// 管乐迷 diff获取不准确时, 弱起补齐
+				if (["2589", "2561", "2560", "2559", "2558", "2556", "2555", "2554"].includes(detailId)) {
+					// difftime = iterator.currentTimeStamp.realValue * formatBeatUnit(beatUnit) * (60 / beatSpeed);
+					// fixtime += difftime;
+				}
+			}
+			let stave = activeVerticalMeasureList[0]?.stave;
+
+			if (note.sourceMeasure.multipleRestMeasures) {
+				totalMultipleRestMeasures = note.sourceMeasure.multipleRestMeasures;
+				multipleRestMeasures = 0;
+			}
+			if (multipleRestMeasures < totalMultipleRestMeasures) {
+				multipleRestMeasures++;
+			} else {
+				multipleRestMeasures = 0;
+				totalMultipleRestMeasures = 0;
+			}
+
+			// console.log(note.tie)
+			const nodeDetail = {
+				isStaccato: note.voiceEntry.isStaccato(),
+				isRestFlag: note.isRestFlag,
+				noteId: note.NoteToGraphicalNoteObjectId,
+				measureListIndex: note.sourceMeasure.measureListIndex,
+				MeasureNumberXML: note.sourceMeasure.MeasureNumberXML,
+				_noteLength: _noteLength,
+				svgElement: svgElement,
+				frequency: note?.pitch?.frequency || -1,
+				nextFrequency: note?.pitch?.nextFrequency || -1,
+				prevFrequency: note?.pitch?.prevFrequency || -1,
+				difftime,
+				octaveOffset: activeVerticalMeasureList[0]?.octaveOffset,
+				speed,
+				beatSpeed,
+				i,
+				si,
+				stepSpeeds,
+				measureOpenIndex: allMeasures.length - 1,
+				measures,
+				tempoInBPM: note.sourceMeasure.tempoInBPM,
+				measureLength,
+				relaMeasureLength,
+				id: svgElement?.attrs.id,
+				note: note.halfTone + 12, // see issue #224
+				relativeTime: retain(relativeTime),
+				time: retain(relativeTime + fixtime),
+				endtime: retain(relaEndtime + fixtime),
+				relaEndtime: retain(relaEndtime),
+				realValue,
+				halfTone: note.halfTone,
+				noteElement: note,
+				fixedKey,
+				realKey: 0,
+				duration: 0,
+				formatLyricsEntries: formatLyricsEntries(note),
+				stave,
+				firstVerticalMeasure: activeVerticalMeasureList[0],
+				noteLength: 1,
+				osdmContext: osmd,
+				speedbeatUnit: beatUnit,
+				multipleRestMeasures: multipleRestMeasures,
+			};
+			nodeDetail.realKey = formatRealKey(note.halfTone - fixedKey * 12, nodeDetail);
+			nodeDetail.duration = nodeDetail.endtime - nodeDetail.time;
+			let tickables = activeVerticalMeasureList[0]?.vfVoices["1"]?.tickables || [];
+			if ([121].includes(state.subjectId)) {
+				tickables = note.sourceMeasure.verticalSourceStaffEntryContainers;
+			}
+			// console.log(note.sourceMeasure.MeasureNumberXML, note.sourceMeasure.verticalSourceStaffEntryContainers.length)
+			nodeDetail.noteLength = tickables.length || 1;
+			allNotes.push(nodeDetail);
+			allNoteId.push(nodeDetail.id);
+			measures.push(nodeDetail);
+			if (si < tickables.length - 1) {
+				si++;
+			} else {
+				si = 0;
+				relaMeasureLength = 0;
+				measures = [];
+			}
+		}
+		i++;
+	}
+	// 按照时间轴排序
+	const sortArray = allNotes.sort((a, b) => a.relativeTime - b.relativeTime).map((item, index) => ({ ...item, i: index }));
+	console.timeEnd("音符跑完时间");
+	try {
+		osmd.cursor.reset();
+	} catch (error) {}
+	state.activeMeasureIndex = sortArray[0].MeasureNumberXML;
+	return sortArray;
+};
+
+/** 获取小节之间的连音线,仅同音高*/
+export const getNoteByMeasuresSlursStart = (note: any) => {
+	let activeNote = note;
+	let tieNote;
+	if (note.noteElement.tie && note.noteElement.tie.StartNote) {
+		tieNote = note.noteElement.tie.StartNote;
+	}
+	if (activeNote && tieNote && tieNote !== activeNote.noteElement) {
+		for (const note of state.times) {
+			if (tieNote === note.noteElement) {
+				return note;
+			}
+		}
+	}
+	return activeNote;
+};

+ 439 - 0
src/helpers/metronome.ts

@@ -0,0 +1,439 @@
+/**
+ * 曲谱节拍器
+ * auth: lsq
+ * time: 2022.11.14
+ */
+import { reactive, watch } from "vue";
+import { tickUrl as tick, tockUrl as tock } from "/src/constant/audios";
+import { browser } from "/src/utils/index";
+import state from "/src/state";
+import { Howl } from "howler";
+import tockAndTick from "/src/constant/tockAndTick.json";
+type IOptions = {
+	speed: number;
+};
+const browserInfo = browser();
+
+export const metronomeData = reactive({
+	disable: true,
+	initPlayerState: false,
+	lineShow: false,
+	isClick: false,
+	metro: null as unknown as Metronome,
+	metroList: [] as number[],
+	activeList: [] as number[],
+	metroMeasure: [] as any[],
+	activeIndex: null as unknown as number,
+	activeMetro: {} as any,
+});
+
+// 切换隐藏光标
+const toggleLine = () => {
+	if (!metronomeData.lineShow) return;
+	const img: HTMLElement = document.querySelector("#cursorImg-0")!;
+	if (img) {
+		if (state.times[state.activeNoteIndex].multipleRestMeasures) {
+			img.classList.remove("lineHide");
+		} else {
+			img.classList.add("lineHide");
+		}
+	}
+};
+watch(
+	() => metronomeData.lineShow,
+	() => {
+		const img: HTMLElement = document.querySelector("#cursorImg-0")!;
+		if (img) {
+			if (metronomeData.lineShow) {
+				img.classList.add("lineHide");
+			} else {
+				img.classList.remove("lineHide");
+			}
+		}
+	}
+);
+
+class Metronome {
+	playType = "tick";
+	source = null as any; // 创建音频源头
+	source1 = null as any;
+	source2 = null as any;
+
+	constructor(option?: IOptions) {}
+	init(times: any[]) {
+		this.calculation(times);
+		metronomeData.activeList = [];
+	}
+	initPlayer() {
+		if (!this.source1) {
+			this.source1 = this.loadAudio1();
+		}
+		if (!this.source2) {
+			this.source2 = this.loadAudio2();
+		}
+		metronomeData.initPlayerState = true;
+	}
+
+	// 播放
+	sound = (currentTime: number) => {
+		if (!state.sectionStatus){
+			currentTime = setCurrentTime(currentTime);
+		}
+		let index = -1;
+		let activeMetro = -1;
+		for (let i = 0; i < metronomeData.metroList.length; i++) {
+			const item = metronomeData.metroList[i];
+
+			if (currentTime >= item) {
+				// console.log(currentTime , item)
+				index = i;
+				activeMetro = item;
+			} else {
+				break;
+			}
+		}
+		if (index > -1 && metronomeData.activeIndex !== index) {
+			metronomeData.activeIndex = index;
+			// console.log("播放", metronomeData.activeIndex);
+			metronomeData.activeMetro = this.getStep(activeMetro);
+			// console.log("🚀 ~ metronomeData.activeMetro",metronomeData.activeMetro.measureNumberIndex, metronomeData.activeMetro.index)
+			this.playAudio();
+			metronomeData.isClick = false;
+			return;
+		}
+		toggleLine()
+		metronomeData.isClick = false;
+	};
+	// 播放
+	playAudio = () => {
+		if (!metronomeData.initPlayerState) return;
+		this.source = metronomeData.activeMetro?.index === 0 ? this.source1 : this.source2;
+		this.source.volume(metronomeData.disable || state.playState === 'paused' ? 0 : 0.4);
+		this.source.play();
+	};
+
+	// 切换
+	selectPlay() {}
+
+	loadAudio1 = () => {
+		return new Howl({
+			src: tockAndTick.tick,
+		});
+	};
+	loadAudio2 = () => {
+		return new Howl({
+			src: tockAndTick.tock,
+		});
+	};
+	getStep(time: number) {
+		for (let i = 0; i < metronomeData.metroMeasure.length; i++) {
+			const list = metronomeData.metroMeasure[i];
+			const item = list.find((n: any) => n.time === time);
+			if (item) {
+				// console.log('index',item)
+				return item;
+			}
+		}
+		return {};
+	}
+
+	// 计算 所有的拍子的时间
+	calculation(times: any[]) {
+		// console.log("🚀 ~ times", times);
+		// 1.统计有多少小节
+		const measures: any[] = [];
+		let xmlNumber = -1;
+		for (let i = 0; i < times.length; i++) {
+			const note = times[i];
+			const measureNumberXML = note?.noteElement?.sourceMeasure?.MeasureNumberXML || -1;
+			// console.log("🚀 ~ note?.noteElement?.sourceMeasure", note?.noteElement?.sourceMeasure)
+			// console.log("🚀 ~ measureNumberXML", measureNumberXML, note)
+			// console.log("🚀 ~ measureNumberXML", note)
+			const measureListIndex = note?.noteElement?.sourceMeasure?.measureListIndex;
+			if (measureNumberXML > -1) {
+				if (measureNumberXML != xmlNumber) {
+					const m = {
+						measureNumberXML: measureNumberXML,
+						measureNumberIndex: measureListIndex,
+						numerator: note?.noteElement?.sourceMeasure?.ActiveTimeSignature?.numerator || 0,
+						start: note.measures[0].time,
+						end: note.measures[note.measures.length - 1].endtime,
+						time: note.measures[note.measures.length - 1].endtime - note.measures[0].time,
+						stave_x: note?.noteElement?.sourceMeasure?.verticalMeasureList?.[0]?.stave?.x || 0,
+						end_x: note?.stave?.end_x || 0 || 0,
+						stepList: [] as number[],
+						svgs: [] as any[],
+						isRestFlag: note.isRestFlag,
+					};
+					// 2.统计小节的拍数
+					// 3.统计小节的时长, 开始时间,结束时间
+					// console.log(measureNumberXML,note.measures, times.filter((n: any) => n?.noteElement?.sourceMeasure?.measureListIndex == measureListIndex))
+					if ([121].includes(state.subjectId)) {
+						const _measures = times.filter((n: any) => n?.noteElement?.sourceMeasure?.measureListIndex == measureListIndex);
+						note.measures = _measures;
+						m.start = note.measures[0].time;
+						m.end = note.measures[note.measures.length - 1].endtime;
+						m.time = note.measures[note.measures.length - 1].endtime - note.measures[0].time;
+						try {
+							const tickables = note.noteElement.sourceMeasure.verticalMeasureList.reduce((arr: any[], value: any) => {
+								arr.push(...value.vfVoices["1"].tickables);
+								return arr;
+							}, []);
+							const xList: any[] = [];
+							m.svgs = tickables
+								.map((n: any) => {
+									const x = n.getBoundingBox().x;
+									if (!xList.includes(x) && n.duration !== "w") {
+										xList.push(x);
+										n._start_x = x;
+										return n;
+									}
+								})
+								.filter(Boolean)
+								.sort((a: any, b: any) => a._start_x - b._start_x);
+							// console.log(measureNumberXML, m.svgs)
+						} catch (error) {
+							console.log(error);
+						}
+						m.stepList = calculateMutilpleMetroStep(note.measures, m);
+					} else {
+						m.stepList = calculateMetroStep(note.measures, m);
+					}
+					measures.push(m);
+					xmlNumber = measureNumberXML;
+				}
+			}
+		}
+		// console.log(measures, measures.length);
+
+		let metroList: number[] = [];
+		const metroMeasure: any[] = [];
+		// 4.按照拍数将时长平均分配
+		try {
+			for (let i = 0; i < measures.length; i++) {
+				const measure = measures[i];
+				const noteStep = measure.time / measure.numerator;
+				// console.log("🚀 ~ measure.measureNumberXML",measure.measureNumberXML, noteStep)
+				const WIDTH = [121].includes(state.subjectId) ? 95 : 100;
+				const widthStep = WIDTH / (measure.numerator + 1);
+				metroMeasure[i] = [] as number[];
+				// console.log('stepList', [...measure.stepList], measure.measureNumberXML)
+				for (let j = 0; j < measure.numerator; j++) {
+					const time = noteStep * j + measure.start;
+					metroList.push(time);
+					let left = "";
+					if (measure.stepList[j]) {
+						left = measure.stepList[j] + "px";
+					} else {
+						const preLeft = measure.stepList[j - 1];
+						left = !preLeft ? `${widthStep}%` : preLeft.toString().indexOf("%") > -1 ? `${preLeft} + ${widthStep}%` : `${preLeft}px + ${widthStep}%`;
+						measure.stepList[j] = left;
+					}
+					metroMeasure[i].push({
+						index: j,
+						time,
+						// left: (measure.stepList[j] ? measure.stepList[j] + 'px' : (j + 1) * widthStep + '%'),
+						left: left?.indexOf("%") > -1 ? `calc(${left})` : left,
+						measureNumberXML: measure.measureNumberXML,
+						isRestFlag: measure.isRestFlag,
+					});
+				}
+			}
+		} catch (error) {
+			console.log(error);
+		}
+		// console.log(metroList, metroMeasure);
+		// 5.得到所有的节拍时间
+		metronomeData.metroList = metroList;
+		metronomeData.metroMeasure = metroMeasure;
+		metronomeData.activeMetro = metroMeasure[0]?.[0] || {};
+	}
+}
+
+// 计算拍子的时值
+function calculateMetroStep(arr: any[], m: any): number[] {
+	const measureLength = arr.reduce((total: number, item: any) => {
+		total += item._noteLength;
+		return total;
+	}, 0);
+	const clap = measureLength / m.numerator;
+	if (arr.length === 1) {
+		const wholeNote = arr[0].svgElement;
+		if (wholeNote && !wholeNote.isRest()) {
+			const measure_bbox = wholeNote?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0, right: 0 };
+			let bbox = wholeNote?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
+			let stepWidth = Math.abs(measure_bbox.right - bbox.x) / m.numerator;
+			let stepList: number[] = [];
+			for (let i = 0; i < m.numerator; i++) {
+				stepList.push(bbox.x - measure_bbox.x + i * stepWidth);
+			}
+			// console.log("🚀 ~ stepList:", stepList, m.measureNumberXML)
+			return stepList;
+		}
+		try {
+			// 开头是休止符
+			if (m.measureNumberXML === 1 && wholeNote && wholeNote.isRest()) {
+				const measure_bbox = wholeNote?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0, right: 0 };
+				let bbox = wholeNote?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
+				let stepWidth = Math.abs(measure_bbox.right - bbox.x) / m.numerator;
+				let stepList: number[] = [];
+				for (let i = -1; i < m.numerator - 1; i++) {
+					stepList.push(bbox.x - measure_bbox.x + i * stepWidth);
+				}
+				// console.log(wholeNote?.attrs?.el, m.measureNumberXML)
+				// console.log("🚀 ~ stepList:", stepList, m.measureNumberXML)
+				return stepList;
+			}
+		} catch (error) {
+			console.log("🚀 ~ error:", error);
+		}
+
+		return [];
+	}
+	// console.log("🚀 ~ arr", [...arr],`小节总时值: ${measureLength}`, clap, m.measureNumberXML);
+	let totalLength = 0;
+	let notes: any[] = [];
+	let stepList: number[] = [];
+	for (let i = 0; i < arr.length; i++) {
+		const item = arr[i];
+		item.index = i;
+		const noteLength = item._noteLength;
+		totalLength += noteLength;
+		// 大于一拍
+		const exceedStep = Math.floor(totalLength / clap);
+		// console.log(`note`, item?.svgElement?.attrs?.el,notes.length,{noteLength, exceedStep,clap}, m.measureNumberXML)
+		if (exceedStep >= 1) {
+			totalLength -= clap;
+			// 一拍
+			const measure_bbox = item?.svgElement?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0 };
+			if (notes.length > 0) {
+				let bbox = notes[0]?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
+				let x: any = bbox.x - measure_bbox.x;
+				if (notes[0]._noteLength / clap >= 1) {
+					const nextNote = arr[notes[0].index + 1]?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: measure_bbox.right } || { x: 0 };
+					const stepWidth = Math.abs(bbox.x - nextNote.x) / 2;
+					x = bbox.x - measure_bbox.x + stepWidth;
+					// console.log(`音符超一拍`, notes[0]?.svgElement?.attrs?.el, arr[notes[0].index + 1]?.svgElement?.attrs?.el, bbox.x - nextNote.x, stepWidth, m.measureNumberXML);
+				}
+				// console.log(`一拍`, notes[0]?.svgElement?.attrs?.el, m.measureNumberXML, notes[0]._noteLength , clap, 'aa')
+				stepList.push(x);
+			} else {
+				let bbox = item?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
+				let x: any = bbox.x - measure_bbox.x;
+				// console.log(`一拍`, item?.svgElement?.attrs?.el, m.measureNumberXML)
+				stepList.push(x);
+			}
+			notes = [];
+			let bbox = item?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
+			let x: any = bbox.x - measure_bbox.x;
+			let stepWidth = 0;
+			if (exceedStep > 1) {
+				// 二拍以上
+				const nextNote = arr[i + 1]?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: measure_bbox.right } || { x: 0 };
+				stepWidth = Math.abs(bbox.x - nextNote.x) / exceedStep;
+				// console.log("二拍以上 ~ nextNote:",bbox.x , nextNote.x,stepWidth, item?.svgElement?.attrs?.el,arr[i + 1]?.svgElement?.attrs?.el, exceedStep);
+			}
+
+			for (let j = 1; j < exceedStep; j++) {
+				totalLength -= clap;
+				// console.log(`超一拍`,item?.svgElement?.attrs?.el, m.measureNumberXML)
+				stepList.push(x + stepWidth * j);
+			}
+		}
+
+		//有时值就将音符加入
+		if (totalLength > Number.EPSILON && totalLength > 0) {
+			notes.push(item);
+		}
+	}
+	stepList = stepList.reduce((list: any[], n: number) => {
+		if (list.includes(n)) {
+			list.push(undefined as any);
+		} else {
+			list.push(n);
+		}
+		return list;
+	}, []);
+	// console.log("stepList", [...stepList], m.measureNumberXML);
+	return stepList;
+}
+// 计算单声部多声轨的拍子的时值
+function calculateMutilpleMetroStep(arr: any[], m: any): number[] {
+	// console.log("🚀 ~ m:", [...m.svgs])
+	const step = m.time / m.numerator;
+	const measure_bbox = arr[0]?.svgElement?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0 };
+	if (arr.length === 1) {
+		const staveNote = m.svgs[0];
+		// 大于一拍
+		let bbox = staveNote?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
+		if (staveNote && !staveNote.isRest()) {
+			return [bbox.x - measure_bbox.x];
+		}
+		return [];
+	}
+	// console.log("🚀 ~ arr", arr, step, m.measureNumberXML);
+	let total = 0;
+	let notes: any[] = [];
+	let stepList: number[] = [];
+	for (let i = 0; i < arr.length; i++) {
+		const item = arr[i];
+		item._index = i;
+		const noteTime = item.endtime - item.time;
+		total += noteTime;
+		let svgEle = m.svgs[i]?.attrs?.el;
+		// 大于一拍
+		let bbox = svgEle?.getBoundingClientRect?.() || { x: 0 };
+		// console.log(m.measureNumberXML, svgEle, i)
+		if (noteTime > step) {
+			total -= step;
+			// console.log('超过一拍了', notes, m.measureNumberXML)
+			let x = bbox.x - measure_bbox.x;
+			if (notes.length > 0) {
+				svgEle = m.svgs[notes[0]._index]?.attrs?.el;
+				bbox = svgEle?.getBoundingClientRect?.() || { x: 0 };
+				x = bbox.x - measure_bbox.x;
+			}
+			stepList.push(x);
+			notes = [];
+		} else {
+			notes.push(item);
+		}
+		// console.log(notes)
+		if (Math.abs(total - step) < 0.001) {
+			let x = bbox.x - measure_bbox.x;
+			if (notes.length > 0) {
+				svgEle = m.svgs[notes[0]._index]?.attrs?.el;
+				bbox = svgEle?.getBoundingClientRect?.() || { x: 0 };
+				x = bbox.x - measure_bbox.x;
+			}
+			// console.log("一拍",svgEle,notes,m.svgs, m.measureNumberXML);
+			stepList.push(x);
+			total = 0;
+			notes = [];
+		}
+	}
+	stepList = stepList.reduce((list: any[], n: number) => {
+		if (list.includes(n)) {
+			list.push(undefined as any);
+		} else {
+			list.push(n);
+		}
+		return list;
+	}, []); //Array.from(new Set(stepList))
+	// console.log('stepList', stepList, m.measureNumberXML)
+	return stepList;
+}
+
+// 延迟兼容处理
+function setCurrentTime(time: number) {
+	if (browserInfo.huawei || browserInfo.xiaomi) {
+		time += 0.125;
+	} else if (browserInfo.android) {
+		time += 0.11;
+	} else if (browserInfo.ios) {
+		time += 0.01;
+	}
+	return time;
+}
+
+export default Metronome;

+ 23 - 0
src/helpers/parseABC.ts

@@ -0,0 +1,23 @@
+/**
+ * 解析ABC曲谱, 获取最小的音符单位
+ * @param abcNotation abc曲谱
+ * @returns 最小的音符单位
+ */
+export const getMinNoteUnit = (abcNotation: string) => {
+	const lines = abcNotation.split("\n");
+	let minNoteUnit = null;
+
+	for (const line of lines) {
+		const regex = /L:(\s*)(\d+\/\d+)/;
+		const match = line.match(regex);
+		console.log("🚀 ~ line:", line, match);
+		// Extract the unit note length from the L: directive.
+		const unitNoteLengthMatch = line.match(regex);
+		if (unitNoteLengthMatch) {
+			minNoteUnit = unitNoteLengthMatch[unitNoteLengthMatch.length - 1];
+			break;
+		}
+	}
+
+	return minNoteUnit;
+};

+ 78 - 0
src/pc/App.tsx

@@ -0,0 +1,78 @@
+import { computed, defineComponent } from "vue";
+import { RouterView } from "vue-router";
+import TheError from "../components/The-error";
+import { setUserInfo, storeData } from "../store";
+import { getQuery } from "../utils/queryString";
+import { employeeQueryUserInfo, studentQueryUserInfo, teacherQueryUserInfo } from "./api";
+import {
+	GlobalThemeOverrides,
+	NConfigProvider,
+	NDialogProvider,
+	NMessageProvider,
+	NNotificationProvider,
+} from "naive-ui";
+import { lighten } from "../utils";
+
+export default defineComponent({
+	name: "App",
+	setup() {
+		const appTheme = "#198CFE";
+		const lightenStr = lighten(appTheme, 6);
+		const themeOverrides: GlobalThemeOverrides = {
+			common: {
+				primaryColor: appTheme,
+				primaryColorHover: lightenStr,
+				primaryColorPressed: lightenStr,
+			},
+			LoadingBar: {
+				colorLoading: appTheme,
+			},
+		};
+		const query: any = getQuery();
+		/** 获取用户信息 */
+		const getUserInfo = async () => {
+			// const a = await request.get(`/student/queryUserInfo`)
+			// console.log(a)
+			if (storeData.platformType === "WEB") {
+				return await employeeQueryUserInfo();
+			} else if (storeData.platformType === "TEACHER") {
+				return await teacherQueryUserInfo();
+			}
+			return await studentQueryUserInfo();
+		};
+		const setUser = async () => {
+			const res = await getUserInfo();
+			const { student } = res?.data || {};
+			setUserInfo(student);
+			// console.log("🚀 ~ res:", res);
+		};
+		// onBeforeMount(() => {
+		// 	if (query.Authorization) {
+		// 		setToken(query.Authorization);
+		// 	}
+		// 	setUser();
+		// 	setBehaviorId(getRandomKey())
+		// 	setCampId(query.campId || '')
+		// });
+		// onMounted(() => {
+		// 	const _loading = document.getElementById("loading")
+		// 	_loading && (document.body.removeChild(_loading))
+		// })
+
+		const inited = computed(() => {
+			return true;
+			// return storeData.status === "login";
+		});
+		return () => (
+			<NConfigProvider inlineThemeDisabled themeOverrides={themeOverrides}>
+				<NDialogProvider>
+					<NNotificationProvider>
+						<NMessageProvider max={1}>
+							{storeData.status === "error" ? <TheError /> : inited.value ? <RouterView /> : null}
+						</NMessageProvider>
+					</NNotificationProvider>
+				</NDialogProvider>
+			</NConfigProvider>
+		);
+	},
+});

+ 70 - 0
src/pc/api.ts

@@ -0,0 +1,70 @@
+import request from "../utils/request";
+
+/** 获取学生信息 */
+export const studentQueryUserInfo = async () => {
+	return await request.get(`/student/queryUserInfo`);
+};
+/** 获取老师信息 */
+export const teacherQueryUserInfo = () => {
+	return request.get(`/teacher/queryUserInfo`);
+};
+/** 后台用户信息 */
+export const employeeQueryUserInfo = () => {
+	return request.get(`/employee/queryUserInfo`);
+};
+
+/** 获取曲谱信息 */
+export const sysMusicScoreAccompanimentQueryPage = (sysMusicScoreId: string) => {
+	return request.get("/sysMusicScoreAccompaniment/queryPage", {
+		params: {
+			clientType: "SMART_PRACTICE",
+			sysMusicScoreId,
+		},
+	});
+};
+
+/** 获取曲谱分类 */
+export const sysMusicScoreCategoriesQueryTree = (enable = false) => {
+	return request.get(`/sysMusicScoreCategories/queryTree`, {
+		params: {
+			parentId: 0,
+			// 后台详情忽略是否启用分类
+			enable,
+		},
+	});
+};
+
+/** 获取曲谱列表 */
+export const sysMusicScoreQueryPage2 = (params: any) => {
+	return request.get(`/sysMusicScore/queryPage2`, { params });
+};
+
+/** 提交意见反馈 */
+export const suggestionAdd = (data: any) => {
+	return request.post("/suggestion/add", { data });
+};
+
+/** 记录训练时长 */
+export const sysMusicRecordAdd = (data: any) => {
+	return request.post("/sysMusicRecord/add", { data });
+};
+/** 获取训练时长 */
+export const tempLittleArtistTrainingCampGetUserTrainingTime = () => {
+	return request.post("/tempLittleArtistTrainingCamp/getUserTrainingTime");
+};
+/** 添加作业记录 */
+export const studentCourseHomeworkAddStudentHomeworkRecord = (params: any) => {
+	return request.get("/studentCourseHomework/addStudentHomeworkRecord", { params });
+};
+/** 获取作业详情 */
+export const studentCourseHomeworkHomeworkDetail = (id: any) => {
+	return request.get(`/studentCourseHomework/homeworkDetail?id=${id}`);
+};
+/** 获取进度详情 */
+export const lessonExaminationGetDetail = (params: any) => {
+	return request.get(`/lessonExamination/getDetail`, { params });
+};
+/** 添加进度评测记录 */
+export const lessonExaminationSubmit = (data: any) => {
+	return request.post(`/lessonExamination/submit`, { data, requestType: 'form' });
+};

+ 140 - 0
src/pc/component/keys/index.module.less

@@ -0,0 +1,140 @@
+.piano {
+    position: fixed;
+    bottom: 0;
+    width: calc(100% - 310px);
+    right: 10px;
+    display: flex;
+    padding: 10px;
+    z-index: 10;
+    transform: translateY(100%);
+    transition: all .3s;
+}
+
+.show {
+    transform: translateY(0);
+}
+
+.pianoItemWrap {
+    position: relative;
+    display: flex;
+    flex: 1;
+    background-color: #ddd;
+
+    .item {
+        position: relative;
+        width: calc(100% / 7);
+        padding-bottom: 80%;
+        margin: 0;
+        background: #fff;
+        background: linear-gradient(-30deg, #f5f5f5, #fff);
+        border: 1px solid #ccc;
+        border-radius: 0 0 5px 5px;
+        cursor: pointer;
+
+        &:hover {
+            box-shadow: inset 0 0 5px 0 orange;
+        }
+
+        &:active {
+            background: #facc94;
+        }
+
+        &.keyDown {
+            background: #efefef;
+            transform: scaleY(0.95);
+            transform-origin: top;
+            &::before {
+                content: "";
+                position: absolute;
+                left: 0;
+                bottom: 0;
+                width: 10%;
+                height: 100%;
+                background: rgba(0,0,0,.1);
+            }
+            &::after{
+                content: "";
+                position: absolute;
+                right: 0;
+                bottom: 0;
+                width: 10%;
+                height: 100%;
+                background: rgba(0,0,0,.1);
+            }
+        }
+    }
+
+    .keytip {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        width: 100%;
+        color: #131415;
+        text-align: center;
+        font-size: 12Px;
+        position: absolute;
+        bottom: 5%;
+    }
+
+    .singname {
+        width: 80%;
+        height: 20px;
+        line-height: 20px;
+        text-align: center;
+        font-weight: 700;
+        font-size: 12px;
+        border-radius: 2px;
+    }
+
+    .bkeyWrap {
+        position: absolute;
+        width: 100%;
+        padding-bottom: 50%;
+        top: 0;
+
+        .bkey {
+            width: 10%;
+            height: 100%;
+            background: linear-gradient(-20deg, #333, #000, #333);
+            border-color: #666 #222 #111 #555;
+            border-style: solid;
+            border-width: 1px 2px 7px;
+            border-radius: 0 0 2px 2px;
+            box-shadow: inset 0 -1px 2px hsla(0, 0%, 100%, .4), 0 2px 3px rgba(0, 0, 0, .4);
+            position: absolute;
+            top: 0;
+            overflow: hidden;
+
+            &:first-child {
+                left: 9%;
+            }
+
+            &:nth-child(2) {
+                left: 24%;
+            }
+
+            &:nth-child(3) {
+                left: 52%;
+            }
+
+            &:nth-child(4) {
+                left: 66%;
+            }
+
+            &:nth-child(5) {
+                left: 81%;
+            }
+
+            &:hover {
+                cursor: pointer;
+                box-shadow: inset 0 0 7px 0 #87cefa;
+            }
+
+            &:active {
+                background: #75c3ed;
+                border-color: #75c3ed;
+            }
+        }
+    }
+
+}

+ 118 - 0
src/pc/component/keys/index.tsx

@@ -0,0 +1,118 @@
+import { defineComponent, onMounted, onUnmounted, reactive } from "vue";
+import styles from "./index.module.less";
+
+export default defineComponent({
+	name: "Keys",
+	emits: ["click"],
+	props: {
+		show: {
+			type: Boolean,
+			default: false,
+		},
+	},
+	setup(props, { emit }) {
+		const data = reactive({
+			keys: [
+				{ key: "C", singname: "do", type: "white" },
+				{ key: "D", singname: "re", type: "white" },
+				{ key: "E", singname: "mi", type: "white" },
+				{ key: "F", singname: "fa", type: "white" },
+				{ key: "G", singname: "so", type: "white" },
+				{ key: "A", singname: "la", type: "white" },
+				{ key: "B", singname: "si", type: "white" },
+			],
+			keyDown: "",
+		});
+		/** 赤橙黄露青蓝紫 */
+		const colors = ["#F07C83", "#FF966C", "#FBB957", "#A7DCBF", "#CCCCD6", "#A5D2FF", "#B0A4F4"];
+		const productKey = (total = 0) => {
+			return new Array(Math.abs(total)).fill(total > 0 ? "'" : ",").join("");
+		};
+
+		const keyDown = (e: KeyboardEvent) => {
+			console.log("🚀 ~ e:", e);
+			data.keyDown = e.key.toLocaleUpperCase();
+		};
+		const keyUp = (e: KeyboardEvent) => {
+			data.keyDown = "";
+		};
+		onMounted(() => {
+			document.addEventListener("keydown", keyDown);
+			document.addEventListener("keyup", keyUp);
+		});
+		onUnmounted(() => {
+			document.removeEventListener("keydown", keyDown);
+			document.removeEventListener("keyup", keyUp);
+		});
+		return () => (
+			<div class={[styles.piano, props.show && styles.show]}>
+				{new Array(7).fill(0).map((_, index) => (
+					<div class={styles.pianoItemWrap}>
+						{data.keys.map((item) => {
+							return (
+								<div
+									class={[styles.item, index === 3 && data.keyDown === item.key && styles.keyDown]}
+									key={index}
+									onClick={() => {
+										emit("click", { type: "note", value: item.key + productKey(index - 3) });
+									}}
+								>
+									<div class={styles.keytip}>
+										<div style={{ color: "#ff4a00" }}>
+											{index === 3 && item.key === "C" ? "中央C" : ""}
+										</div>
+										<div class={styles.keyname}>
+											{item.key}
+											{index + 1}
+										</div>
+										<div class={styles.singname} style={{ background: colors[index] }}>
+											{item.singname}
+										</div>
+									</div>
+								</div>
+							);
+						})}
+						<div class={styles.bkeyWrap}>
+							{data.keys.map((item) => {
+								if (item.key === "E" || item.key === "B") return null;
+								return (
+									<div
+										class={styles.bkey}
+										onClick={() => {
+											emit("click", {
+												type: "note",
+												value: item.key + productKey(index - 3) + "-" + "^",
+											});
+										}}
+									>
+										<div class="keytip"></div>
+									</div>
+								);
+							})}
+							{/* <div
+								class={styles.bkey}
+								onClick={() => {
+									// emit("click", { type: "note", value: item.key + productKey(index - 3) });
+								}}
+							>
+								<div class="keytip"></div>
+							</div>
+							<div class={styles.bkey}>
+								<div class="keytip"></div>
+							</div>
+							<div class={styles.bkey}>
+								<div class="keytip"></div>
+							</div>
+							<div class={styles.bkey}>
+								<div class="keytip"></div>
+							</div>
+							<div class={styles.bkey}>
+								<div class="keytip"></div>
+							</div> */}
+						</div>
+					</div>
+				))}
+			</div>
+		);
+	},
+});

+ 6 - 0
src/pc/component/notes/index.module.less

@@ -0,0 +1,6 @@
+.noteTypes{
+    display: flex;
+    & > div {
+        margin: 0 10px;
+    }
+}

+ 78 - 0
src/pc/component/notes/index.tsx

@@ -0,0 +1,78 @@
+import { defineComponent, reactive } from "vue";
+import styles from "./index.module.less";
+import { Checkbox, CheckboxGroup, Radio, RadioGroup } from "vant";
+import { ABC_DATA } from "../../home/runtime";
+
+
+export default defineComponent({
+	name: "Notes",
+	emits: ["change"],
+	setup(props, { emit }) {
+		const data = reactive({
+			type: "",
+			clef: "[K:treble]",
+			key: "C",
+			meter: "4/4",
+		});
+		return () => (
+			<div>
+				<RadioGroup
+					v-model={data.type}
+					class={styles.noteTypes}
+					onChange={() => {
+						emit("change", { type: "type", value: data.type });
+					}}
+				>
+					{ABC_DATA.types.map((item) => {
+						return <Radio name={item.value}>{item.name}</Radio>;
+					})}
+				</RadioGroup>
+				<div>
+					<div>临时升降记号</div>
+					{ABC_DATA.accidentals.map((item) => (
+						<button onClick={() => emit("change", { type: "accidentals", value: item.value })}>
+							{item.name}
+						</button>
+					))}
+					<div>谱号</div>
+					{ABC_DATA.clef.map((item) => (
+						<button onClick={() => emit("change", { type: "clef", value: item.value })}>
+							{item.name}
+						</button>
+					))}
+					<div>调号</div>
+					{ABC_DATA.key.map((item) => (
+						<button onClick={() => emit("change", { type: "key", value: item.value })}>
+							{item.name}
+						</button>
+					))}
+					<div>拍号</div>
+					{ABC_DATA.meter.map((item) => (
+						<button onClick={() => emit("change", { type: "meter", value: item.value })}>
+							{item.name}
+						</button>
+					))}
+					<div>演奏技法</div>
+					{ABC_DATA.play.map((item) => (
+						<button onClick={() => emit("change", { type: "play", value: item.value })}>
+							{item.name}
+						</button>
+					))}
+
+					<div>连线</div>
+					{ABC_DATA.tie.map((item) => (
+						<button onClick={() => emit("change", { type: "tie", value: item.value })}>
+							{item.name}
+						</button>
+					))}
+					<div>力度记号</div>
+					{ABC_DATA.dynamics.map((item) => (
+						<button onClick={() => emit("change", { type: "dynamics", value: item.value })}>
+							{item.name}
+						</button>
+					))}
+				</div>
+			</div>
+		);
+	},
+});

+ 49 - 0
src/pc/home/component/file-btn/index.module.less

@@ -0,0 +1,49 @@
+.btnImg {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 46px;
+    height: 46px;
+    border-radius: 6px;
+    margin-bottom: 1px;
+
+    &:hover {
+        background-color: rgba(0, 0, 0, 0.1);
+    }
+
+    .topBtnIcon {
+        width: 42px;
+        height: 42px;
+    }
+}
+.dropItem {
+    display: flex;
+    align-items: center;
+
+    .dropIcon {
+        width: 24px;
+        height: 25px;
+        margin-right: 12px;
+    }
+}
+
+.dropWrap:global(.n-dropdown-menu) {
+    background: #FFFFFF;
+    box-shadow: 0px 2px 17px 0px rgba(0, 0, 0, 0.08);
+    border-radius: 12px;
+    --n-padding: 10px 12px;
+    --n-border-radius: 6px;
+    :global {
+        .n-dropdown-menu{
+            min-width: 120px;
+        }
+
+        .n-dropdown-option-body {
+            padding: 0 12px;
+            --n-option-height: 45px;
+            .n-dropdown-option-body__prefix{
+                display: none;
+            }
+        }
+    }
+}

+ 104 - 0
src/pc/home/component/file-btn/index.tsx

@@ -0,0 +1,104 @@
+import { NDropdown } from "naive-ui";
+import { defineComponent } from "vue";
+import styles from "./index.module.less";
+import { getImage } from "../../images";
+import { DropdownMixedOption } from "naive-ui/es/dropdown/src/interface";
+
+/** 新建 | 保存 | 导入 | 上传 | 导出 | 打印 */
+export type IFileBtnType = 'newMusic' | 'save' | 'xml' | 'upload' | 'png' | 'wav' | 'midi' | 'print'
+
+export default defineComponent({
+	name: "FileBtn",
+	emits: ["select"],
+	setup(props, { emit }) {
+		const options: DropdownMixedOption[] = [
+			{
+				label: "新建曲谱",
+				key: "newMusic",
+			},
+			{
+				label: () => (
+					<div class={styles.dropItem}>
+						<img class={styles.dropIcon} src={getImage("icon_26_0.png")} />
+						<span>保存</span>
+					</div>
+				),
+				key: "save",
+				disabled: true
+			},
+			{
+				label: () => (
+					<div class={styles.dropItem}>
+						<img class={styles.dropIcon} src={getImage("icon_26_0.png")} />
+						<span>导入</span>
+					</div>
+				),
+				key: "import",
+				children: [
+					{
+						label: "xml",
+                        key: 'xml'
+					},
+				],
+			},
+			{
+				label: () => (
+					<div class={styles.dropItem}>
+						<img class={styles.dropIcon} src={getImage("icon_26_1.png")} />
+						<span>上传到我的资源</span>
+					</div>
+				),
+				key: "upload",
+				disabled: true
+			},
+			{
+				label: () => (
+					<div class={styles.dropItem}>
+						<img class={styles.dropIcon} src={getImage("icon_26_2.png")} />
+						<span>导出</span>
+					</div>
+				),
+				key: "export",
+				children: [
+					{
+						label: "PNG",
+						key: "png",
+					},
+					{
+						label: "WAV",
+						key: "wav",
+					},
+					{
+						label: "MIDI",
+						key: "midi",
+					},
+				],
+			},
+			{
+				label: () => (
+					<div class={styles.dropItem}>
+						<img class={styles.dropIcon} src={getImage("icon_26_3.png")} />
+						<span>打印</span>
+					</div>
+				),
+				key: "print",
+				disabled: true
+			},
+		];
+		return () => (
+			<NDropdown
+				class={styles.dropWrap}
+				options={options}
+				trigger="click"
+				onSelect={(val) => {
+					console.log("🚀 ~ val:", val);
+                    emit("select", val);
+				}}
+			>
+				<div class={styles.btnImg}>
+					<img class={styles.topBtnIcon} src={getImage("icon_0.png")} />
+				</div>
+			</NDropdown>
+		);
+	},
+});

+ 26 - 0
src/pc/home/component/the-btn/index.module.less

@@ -0,0 +1,26 @@
+.btn{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    cursor: pointer;
+}
+.icon{
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 36px;
+    padding: 4px;
+    border-radius: 2px;
+    &:hover{
+        background-color: rgba(0,0,0,0.1);
+    }
+}
+.name{
+    font-size: 12px;
+    color: #333;
+}
+.active{
+    .icon{
+        background-color: rgba(193,219,251,1);
+    }
+}

+ 39 - 0
src/pc/home/component/the-btn/index.tsx

@@ -0,0 +1,39 @@
+import { PropType, defineComponent } from "vue";
+import styles from "./index.module.less";
+import TheIcon from "/src/components/The-icon";
+
+export default defineComponent({
+	name: "TheBtn",
+	props: {
+		icon: {
+			type: String,
+			default: "",
+		},
+		name: {
+			type: String,
+			default: "",
+		},
+		showName: {
+			type: Boolean,
+			default: true,
+		},
+		active: {
+			type: Boolean,
+			default: false,
+		},
+        size: {
+            type: Array as PropType<string[]>,
+			default: ["1em", "1em"],
+        }
+	},
+	setup(props) {
+		return () => (
+			<div class={[styles.btn, props.active && styles.active]} title={props.name}>
+				<div class={styles.icon}>
+					<TheIcon iconClassName={props.icon} size={props.size} />
+				</div>
+				{props.showName && <div class={styles.name}>{props.name}</div>}
+			</div>
+		);
+	},
+});

+ 0 - 0
src/pc/home/component/the-setting/index.module.less


+ 30 - 0
src/pc/home/component/the-setting/index.tsx

@@ -0,0 +1,30 @@
+import { NIcon, NModal } from "naive-ui";
+import { defineComponent, reactive } from "vue";
+import { Close } from "@vicons/ionicons5";
+
+export default defineComponent({
+	name: "TheSetting",
+	props: {
+		show: {
+			type: Boolean,
+			default: false,
+		},
+	},
+	emits: ["update:show"],
+	setup(props, { emit }) {
+		const data = reactive({
+			show: false,
+		});
+		return () => (
+			<NModal show={props.show}>
+				<div>
+					<div>设置</div>
+					<div onClick={() => emit('update:show', false)}>
+						<NIcon component={Close} />
+					</div>
+				</div>
+				<div></div>
+			</NModal>
+		);
+	},
+});

+ 8 - 0
src/pc/home/component/the-speed/index.module.less

@@ -0,0 +1,8 @@
+.speedEdit{
+    padding-top: 8px;
+    display: flex;
+    align-items: center;
+    .speedIcon{
+        font-size: 30px;
+    }
+}

+ 49 - 0
src/pc/home/component/the-speed/index.tsx

@@ -0,0 +1,49 @@
+import { defineComponent, reactive } from "vue";
+import styles from "./index.module.less";
+import TheIcon from "/src/components/The-icon";
+import { Button, Input, Space } from "@varlet/ui";
+import { NButton, NInputNumber } from "naive-ui";
+
+export default defineComponent({
+	name: "TheSpeed",
+	emits: ["change"],
+	setup(props, { emit }) {
+		const data = reactive({
+			speed: 80,
+			status: "",
+		});
+		return () => (
+			<div>
+				<div class={styles.speedEdit}>
+					<NInputNumber
+						size="large"
+						v-model:value={data.speed}
+						showButton={false}
+						min={1}
+						onUpdateValue={(val) => {
+							console.log("🚀 ~ val:", val)
+							data.status = /^\+?[1-9]\d*$/.test(val + "") ? "" : "error";
+						}}
+					>
+						{{
+							prefix: () => (
+								<div class={styles.speedIcon}>
+									<TheIcon iconClassName="icon-a-sudu-4fenyinfu" size={["2em", "1em"]} />
+								</div>
+							),
+							suffix: () => (
+								<NButton
+									text
+									type="primary"
+									onClick={() => emit("change", { type: "speeds", value: "Q:1/4=" + data.speed })}
+								>
+									使用
+								</NButton>
+							),
+						}}
+					</NInputNumber>
+				</div>
+			</div>
+		);
+	},
+});

BIN
src/pc/home/images/icon_0.png


BIN
src/pc/home/images/icon_1.png


BIN
src/pc/home/images/icon_10.png


BIN
src/pc/home/images/icon_11.png


BIN
src/pc/home/images/icon_12.png


BIN
src/pc/home/images/icon_13.png


BIN
src/pc/home/images/icon_14.png


BIN
src/pc/home/images/icon_15.png


BIN
src/pc/home/images/icon_16.png


BIN
src/pc/home/images/icon_17.png


BIN
src/pc/home/images/icon_18.png


BIN
src/pc/home/images/icon_19.png


Деякі файли не було показано, через те що забагато файлів було змінено