diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index eaf98f7..0000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,38 +0,0 @@
-module.exports = {
- root: true,
- env: {
- node: true
- },
- extends: [
- "plugin:vue/vue3-essential",
- "eslint:recommended",
- "@vue/typescript/recommended"
- ],
- parserOptions: {
- ecmaVersion: 2020
- },
- rules: {
- "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
- "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
- "no-unused-vars": "off",
- "@typescript-eslint/no-unused-vars": [
- "error",
- { "argsIgnorePattern": "^_" }
- ]
- },
- overrides: [
- {
- files: [
- "**/__tests__/*.{j,t}s?(x)",
- "**/tests/unit/**/*.spec.{j,t}s?(x)",
- "*.js"
- ],
- rules: {
- "@typescript-eslint/no-var-requires": "off",
- },
- env: {
- jest: true
- }
- }
- ]
-};
diff --git a/.gitignore b/.gitignore
index 20128fc..75d5ca4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
.DS_Store
-node_modules
+/node_modules
/dist
/crate/target/*
/.log
@@ -28,10 +28,3 @@ pnpm-debug.log*
#Electron-builder output
/dist_electron
-
-#Electron-builder config
-electron-builder.yml
-
-#Window and session states
-session.json
-window.json
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..936e781
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,2 @@
+@crimata:registry=https://gitlab.com/api/v4/projects/28849281/packages/npm/
+//gitlab.com/api/v4/projects/28849281/packages/npm/:_authToken=${NPM_TOKEN}
\ No newline at end of file
diff --git a/babel.config.js b/babel.config.js
deleted file mode 100644
index e955840..0000000
--- a/babel.config.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = {
- presets: [
- '@vue/cli-plugin-babel/preset'
- ]
-}
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index d7f13cc..0000000
--- a/jest.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
- transform: {
- '^.+\\.vue$': 'vue-jest'
- }
-}
diff --git a/jsconfig.json b/jsconfig.json
deleted file mode 100644
index 5df65d0..0000000
--- a/jsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "typeAcquisition": {
-
- "enable": true
- }
-}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..82bd044
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2213 @@
+{
+ "name": "Crimata",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "Crimata",
+ "version": "1.0.0",
+ "dependencies": {
+ "@crimata/nodeaudio": "^0.0.0",
+ "axios": "^0.21.1",
+ "base64-arraybuffer": "^1.0.1",
+ "electron-store": "^8.0.0",
+ "ws": "^7.3.1"
+ },
+ "devDependencies": {
+ "electron": "^13.2.3"
+ }
+ },
+ "node_modules/@crimata/nodeaudio": {
+ "version": "0.0.0",
+ "resolved": "https://gitlab.com/api/v4/projects/28849281/packages/npm/@crimata/nodeaudio/-/@crimata/nodeaudio-0.0.0.tgz",
+ "integrity": "sha1-KTpDGuL8j3x72BLNb4Iyg8zgARo=",
+ "hasInstallScript": true,
+ "dependencies": {
+ "bindings": "~1.2.1",
+ "sleep": "^6.3.0"
+ }
+ },
+ "node_modules/@electron/get": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.0.tgz",
+ "integrity": "sha512-+SjZhRuRo+STTO1Fdhzqnv9D2ZhjxXP6egsJ9kiO8dtP68cDx7dFCwWi64dlMQV7sWcfW1OYCW4wviEBzmRsfQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "env-paths": "^2.2.0",
+ "fs-extra": "^8.1.0",
+ "got": "^9.6.0",
+ "progress": "^2.0.3",
+ "semver": "^6.2.0",
+ "sumchecker": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ },
+ "optionalDependencies": {
+ "global-agent": "^2.0.2",
+ "global-tunnel-ng": "^2.7.1"
+ }
+ },
+ "node_modules/@electron/get/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/@electron/get/node_modules/jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/@electron/get/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@electron/get/node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "dependencies": {
+ "defer-to-connect": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "14.17.12",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.12.tgz",
+ "integrity": "sha512-vhUqgjJR1qxwTWV5Ps5txuy2XMdf7Fw+OrdChRboy8BmWUPkckOhphaohzFG6b8DW7CrxaBMdrdJ47SYFq1okw==",
+ "dev": true
+ },
+ "node_modules/ajv": {
+ "version": "8.6.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
+ "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/atomically": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz",
+ "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==",
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/axios": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+ "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+ "dependencies": {
+ "follow-redirects": "^1.10.0"
+ }
+ },
+ "node_modules/base64-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz",
+ "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/bindings": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
+ "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
+ },
+ "node_modules/boolean": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz",
+ "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "node_modules/cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "engines": [
+ "node >= 0.8"
+ ],
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/conf": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/conf/-/conf-10.0.2.tgz",
+ "integrity": "sha512-iyy4ArqyQ/yrzNASNBN+jaylu53JRuq0ztvL6KAWYHj4iN56BVuhy2SrzEEHBodNbacZr2Pd/4nWhoAwc66T1g==",
+ "dependencies": {
+ "ajv": "^8.1.0",
+ "ajv-formats": "^2.0.2",
+ "atomically": "^1.7.0",
+ "debounce-fn": "^4.0.0",
+ "dot-prop": "^6.0.1",
+ "env-paths": "^2.2.1",
+ "json-schema-typed": "^7.0.3",
+ "onetime": "^5.1.2",
+ "pkg-up": "^3.1.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "3.16.3",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.3.tgz",
+ "integrity": "sha512-lM3GftxzHNtPNUJg0v4pC2RC6puwMd6VZA7vXUczi+SKmCWSf4JwO89VJGMqbzmB7jlK7B5hr3S64PqwFL49cA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "node_modules/debounce-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz",
+ "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==",
+ "dependencies": {
+ "mimic-fn": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+ "dev": true
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "object-keys": "^1.0.12"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/dot-prop": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
+ "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "node_modules/electron": {
+ "version": "13.2.3",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-13.2.3.tgz",
+ "integrity": "sha512-FzWhbKHjq7ZTpPQFaYiLPL64erC8/BOsu5NlNN9nQ6f7rIP8ygKlNAlQit3vbOcksQAwItDUCIw4sW0mcaRpCA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "@electron/get": "^1.0.1",
+ "@types/node": "^14.6.2",
+ "extract-zip": "^1.0.3"
+ },
+ "bin": {
+ "electron": "cli.js"
+ },
+ "engines": {
+ "node": ">= 8.6"
+ }
+ },
+ "node_modules/electron-store": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.0.0.tgz",
+ "integrity": "sha512-ZgRPUZkfrrjWSqxZeaxu7lEvmYf6tgl49dLMqxXGnEmliSiwv3u4rJPG+mH3fBQP9PBqgSh4TCuxHZImMMUgWg==",
+ "dependencies": {
+ "conf": "^10.0.0",
+ "type-fest": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/extract-zip": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
+ "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
+ "dev": true,
+ "dependencies": {
+ "concat-stream": "^1.6.2",
+ "debug": "^2.6.9",
+ "mkdirp": "^0.5.4",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ }
+ },
+ "node_modules/extract-zip/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/extract-zip/node_modules/mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/extract-zip/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+ "dev": true,
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dependencies": {
+ "locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.2.tgz",
+ "integrity": "sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/global-agent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz",
+ "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "core-js": "^3.6.5",
+ "es6-error": "^4.1.1",
+ "matcher": "^3.0.0",
+ "roarr": "^2.15.3",
+ "semver": "^7.3.2",
+ "serialize-error": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/global-tunnel-ng": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz",
+ "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "encodeurl": "^1.0.2",
+ "lodash": "^4.17.10",
+ "npm-conf": "^1.1.3",
+ "tunnel": "^0.0.6"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz",
+ "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
+ "dev": true
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+ "dev": true
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
+ },
+ "node_modules/json-schema-typed": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz",
+ "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A=="
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dependencies": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/matcher": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
+ "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "escape-string-regexp": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/matcher/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
+ "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/nan": {
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
+ },
+ "node_modules/normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm-conf": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
+ "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "config-chain": "^1.1.11",
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/onetime/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dependencies": {
+ "p-limit": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-up": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
+ "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
+ "dependencies": {
+ "find-up": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "dependencies": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/roarr": {
+ "version": "2.15.4",
+ "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
+ "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "detect-node": "^2.0.4",
+ "globalthis": "^1.0.1",
+ "json-stringify-safe": "^5.0.1",
+ "semver-compare": "^1.0.0",
+ "sprintf-js": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "type-fest": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/serialize-error/node_modules/type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/sleep": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/sleep/-/sleep-6.3.0.tgz",
+ "integrity": "sha512-+WgYl951qdUlb1iS97UvQ01pkauoBK9ML9I/CMPg41v0Ze4EyMlTgFTDDo32iYj98IYqxIjDMRd+L71lawFfpQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "nan": "^2.14.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/sumchecker": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
+ "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
+ "node_modules/to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
+ "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
+ "dependencies": {
+ "prepend-http": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "node_modules/ws": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz",
+ "integrity": "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg==",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+ "dev": true,
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ }
+ },
+ "dependencies": {
+ "@crimata/nodeaudio": {
+ "version": "0.0.0",
+ "resolved": "https://gitlab.com/api/v4/projects/28849281/packages/npm/@crimata/nodeaudio/-/@crimata/nodeaudio-0.0.0.tgz",
+ "integrity": "sha1-KTpDGuL8j3x72BLNb4Iyg8zgARo=",
+ "requires": {
+ "bindings": "~1.2.1",
+ "sleep": "^6.3.0"
+ }
+ },
+ "@electron/get": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.0.tgz",
+ "integrity": "sha512-+SjZhRuRo+STTO1Fdhzqnv9D2ZhjxXP6egsJ9kiO8dtP68cDx7dFCwWi64dlMQV7sWcfW1OYCW4wviEBzmRsfQ==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "env-paths": "^2.2.0",
+ "fs-extra": "^8.1.0",
+ "global-agent": "^2.0.2",
+ "global-tunnel-ng": "^2.7.1",
+ "got": "^9.6.0",
+ "progress": "^2.0.3",
+ "semver": "^6.2.0",
+ "sumchecker": "^3.0.1"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ }
+ }
+ },
+ "@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true
+ },
+ "@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "requires": {
+ "defer-to-connect": "^1.0.1"
+ }
+ },
+ "@types/node": {
+ "version": "14.17.12",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.12.tgz",
+ "integrity": "sha512-vhUqgjJR1qxwTWV5Ps5txuy2XMdf7Fw+OrdChRboy8BmWUPkckOhphaohzFG6b8DW7CrxaBMdrdJ47SYFq1okw==",
+ "dev": true
+ },
+ "ajv": {
+ "version": "8.6.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
+ "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "requires": {
+ "ajv": "^8.0.0"
+ }
+ },
+ "atomically": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz",
+ "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w=="
+ },
+ "axios": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+ "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+ "requires": {
+ "follow-redirects": "^1.10.0"
+ }
+ },
+ "base64-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz",
+ "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA=="
+ },
+ "bindings": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
+ "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
+ },
+ "boolean": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz",
+ "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==",
+ "dev": true,
+ "optional": true
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "dev": true
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true
+ }
+ }
+ },
+ "clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "conf": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/conf/-/conf-10.0.2.tgz",
+ "integrity": "sha512-iyy4ArqyQ/yrzNASNBN+jaylu53JRuq0ztvL6KAWYHj4iN56BVuhy2SrzEEHBodNbacZr2Pd/4nWhoAwc66T1g==",
+ "requires": {
+ "ajv": "^8.1.0",
+ "ajv-formats": "^2.0.2",
+ "atomically": "^1.7.0",
+ "debounce-fn": "^4.0.0",
+ "dot-prop": "^6.0.1",
+ "env-paths": "^2.2.1",
+ "json-schema-typed": "^7.0.3",
+ "onetime": "^5.1.2",
+ "pkg-up": "^3.1.0",
+ "semver": "^7.3.5"
+ }
+ },
+ "config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "core-js": {
+ "version": "3.16.3",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.3.tgz",
+ "integrity": "sha512-lM3GftxzHNtPNUJg0v4pC2RC6puwMd6VZA7vXUczi+SKmCWSf4JwO89VJGMqbzmB7jlK7B5hr3S64PqwFL49cA==",
+ "dev": true,
+ "optional": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "debounce-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz",
+ "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==",
+ "requires": {
+ "mimic-fn": "^3.0.0"
+ }
+ },
+ "debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "optional": true
+ },
+ "dot-prop": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
+ "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
+ "requires": {
+ "is-obj": "^2.0.0"
+ }
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "electron": {
+ "version": "13.2.3",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-13.2.3.tgz",
+ "integrity": "sha512-FzWhbKHjq7ZTpPQFaYiLPL64erC8/BOsu5NlNN9nQ6f7rIP8ygKlNAlQit3vbOcksQAwItDUCIw4sW0mcaRpCA==",
+ "dev": true,
+ "requires": {
+ "@electron/get": "^1.0.1",
+ "@types/node": "^14.6.2",
+ "extract-zip": "^1.0.3"
+ }
+ },
+ "electron-store": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.0.0.tgz",
+ "integrity": "sha512-ZgRPUZkfrrjWSqxZeaxu7lEvmYf6tgl49dLMqxXGnEmliSiwv3u4rJPG+mH3fBQP9PBqgSh4TCuxHZImMMUgWg==",
+ "requires": {
+ "conf": "^10.0.0",
+ "type-fest": "^1.0.2"
+ }
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true,
+ "optional": true
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="
+ },
+ "es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true,
+ "optional": true
+ },
+ "extract-zip": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
+ "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.6.2",
+ "debug": "^2.6.9",
+ "mkdirp": "^0.5.4",
+ "yauzl": "^2.10.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.2.tgz",
+ "integrity": "sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA=="
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "global-agent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz",
+ "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "boolean": "^3.0.1",
+ "core-js": "^3.6.5",
+ "es6-error": "^4.1.1",
+ "matcher": "^3.0.0",
+ "roarr": "^2.15.3",
+ "semver": "^7.3.2",
+ "serialize-error": "^7.0.1"
+ }
+ },
+ "global-tunnel-ng": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz",
+ "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "encodeurl": "^1.0.2",
+ "lodash": "^4.17.10",
+ "npm-conf": "^1.1.3",
+ "tunnel": "^0.0.6"
+ }
+ },
+ "globalthis": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz",
+ "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "define-properties": "^1.1.3"
+ }
+ },
+ "got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
+ "dev": true
+ },
+ "http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+ "dev": true
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true,
+ "optional": true
+ },
+ "is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
+ },
+ "json-schema-typed": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz",
+ "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A=="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true,
+ "optional": true
+ },
+ "keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "requires": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "optional": true
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "matcher": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
+ "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "escape-string-regexp": "^4.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "mimic-fn": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
+ "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ=="
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "nan": {
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
+ },
+ "normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "dev": true
+ },
+ "npm-conf": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
+ "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "config-chain": "^1.1.11",
+ "pify": "^3.0.0"
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "optional": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ },
+ "dependencies": {
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
+ }
+ }
+ },
+ "p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "optional": true
+ },
+ "pkg-up": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
+ "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
+ "requires": {
+ "find-up": "^3.0.0"
+ }
+ },
+ "prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+ "dev": true,
+ "optional": true
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
+ },
+ "responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "roarr": {
+ "version": "2.15.4",
+ "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
+ "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "boolean": "^3.0.1",
+ "detect-node": "^2.0.4",
+ "globalthis": "^1.0.1",
+ "json-stringify-safe": "^5.0.1",
+ "semver-compare": "^1.0.0",
+ "sprintf-js": "^1.1.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+ "dev": true,
+ "optional": true
+ },
+ "serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "type-fest": "^0.13.1"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "sleep": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/sleep/-/sleep-6.3.0.tgz",
+ "integrity": "sha512-+WgYl951qdUlb1iS97UvQ01pkauoBK9ML9I/CMPg41v0Ze4EyMlTgFTDDo32iYj98IYqxIjDMRd+L71lawFfpQ==",
+ "requires": {
+ "nan": "^2.14.1"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true,
+ "optional": true
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "sumchecker": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
+ "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0"
+ }
+ },
+ "to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true
+ },
+ "tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true,
+ "optional": true
+ },
+ "type-fest": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
+ "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
+ "requires": {
+ "prepend-http": "^2.0.0"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "ws": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz",
+ "integrity": "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg==",
+ "requires": {}
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+ "dev": true,
+ "requires": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 24d13b1..31bd08d 100644
--- a/package.json
+++ b/package.json
@@ -1,104 +1,24 @@
{
"name": "Crimata",
- "version": "0.9.9",
+ "productName": "crimata-messenger",
+ "version": "1.0.0",
"private": true,
- "description": "Cross-platform messenger application built with electron, vue3, and TS.",
+ "description": "Cross-platform messenger app (Electron, Vue3, and TS)",
"author": {
- "name": "Enrique Hernandez"
+ "name": "Andrew Gundersen"
},
+ "main": "src/main.js",
"scripts": {
- "build": "vue-cli-service electron:build",
- "dev": "vue-cli-service electron:serve",
- "postinstall": "electron-builder install-app-deps",
- "postuninstall": "electron-builder install-app-deps"
+ "start": "electron ."
},
- "main": "init.js",
"dependencies": {
- "@google-cloud/speech": "^4.2.0",
- "@types/animejs": "^3.1.2",
- "@types/bindings": "^1.3.0",
- "@types/dom-mediacapture-record": "^1.0.7",
- "@types/node": "^14.14.25",
- "@types/uuid": "^8.3.0",
- "@types/ws": "^7.2.7",
- "animejs": "^3.2.0",
+ "@crimata/nodeaudio": "^0.0.0",
"axios": "^0.21.1",
- "core-js": "^3.6.5",
- "electron-is-dev": "^2.0.0",
+ "base64-arraybuffer": "^1.0.1",
"electron-store": "^8.0.0",
- "electron-updater": "^4.3.8",
- "mitt": "^2.1.0",
- "naudiodon": "^2.3.2",
- "node-record-lpcm16": "^1.0.1",
- "update-electron-app": "^2.0.1",
- "uuid": "^8.3.2",
- "vue": "^3.0.0-0",
- "vue-router": "^4.0.0-0",
- "vuex": "^4.0.0-0",
"ws": "^7.3.1"
},
"devDependencies": {
- "@types/axios": "^0.14.0",
- "@types/electron-devtools-installer": "^2.2.0",
- "@types/jest": "^24.0.19",
- "@typescript-eslint/eslint-plugin": "^2.33.0",
- "@typescript-eslint/parser": "^2.33.0",
- "@vue/cli-plugin-babel": "~4.5.0",
- "@vue/cli-plugin-eslint": "~4.5.0",
- "@vue/cli-plugin-router": "~4.5.0",
- "@vue/cli-plugin-typescript": "~4.5.0",
- "@vue/cli-plugin-unit-jest": "~4.5.0",
- "@vue/cli-plugin-vuex": "~4.5.0",
- "@vue/cli-service": "~4.5.0",
- "@vue/compiler-sfc": "^3.0.0-0",
- "@vue/eslint-config-typescript": "^5.0.2",
- "@vue/test-utils": "^2.0.0-0",
- "@wasm-tool/wasm-pack-plugin": "^1.3.1",
- "electron": "^9.0.0",
- "electron-devtools-installer": "^3.1.0",
- "electron-log": "^4.3.4",
- "eslint": "^6.7.2",
- "eslint-plugin-vue": "^7.0.0-0",
- "lint-staged": "^9.5.0",
- "node-sass": "^4.12.0",
- "optimize-wasm-webpack-plugin": "^1.0.12",
- "sass-loader": "^8.0.2",
- "spectron": "11.0.0",
- "typescript": "~3.9.3",
- "vue-cli-plugin-electron-builder": "~2.0.0-rc.6",
- "vue-jest": "^5.0.0-0"
- },
- "vue": {
- "lintOnSave": false,
- "pluginOptions": {
- "electronBuilder": {
- "mainProcessFile": "./src/init.ts",
- "rendererProcessFile": "./src/render/main.ts",
- "preload": "./src/render/preload.ts",
- "builderOptions": {
- "appId": "com.crimata.ElectronUpdaterApp",
- "artifactName": "${productName}-${version}.${ext}",
- "publish": {
- "provider": "generic",
- "url": "https://gitlab.com/api/v4/projects/25637892/jobs/artifacts/main/raw/dist_electron?job=build"
- }
- }
- }
- }
- },
- "gitHooks": {
- "pre-commit": "lint-staged"
- },
- "lint-staged": {
- "*.{js,jsx,vue,ts,tsx}": [
- "vue-cli-service lint",
- "git add"
- ]
- },
- "productName": "crimata-messenger",
- "repository": {
- "type": "git",
- "url": "https://gitlab.com/crimata/electron-app.git",
- "release": "latest"
+ "electron": "^13.2.3"
}
}
diff --git a/public/index.html b/public/index.html
deleted file mode 100644
index 8f79d27..0000000
--- a/public/index.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
- <%= htmlWebpackPlugin.options.title %>
-
-
-
- We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
-
-
-
-
-
diff --git a/src/account.js b/src/account.js
new file mode 100644
index 0000000..239d89d
--- /dev/null
+++ b/src/account.js
@@ -0,0 +1,44 @@
+const { ipcMain } = require("electron");
+
+const store = require("./utils/store");
+const { postLogin } = require("./api");
+const { ipcEmit } = require("./utils/emitter");
+const { launchSession, endSession } = require("./session");
+
+// store.set("account", "smith12@gmail.com");
+store.set("account", "adgundersen@gmail.com");
+
+async function login(_e, email, password)
+{
+ const res = await postLogin(email, password);
+ if (res)
+ {
+ const account = res.crimataId;
+ store.set("account", account);
+ ipcEmit("set-account", account);
+ launchSession(account);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+};
+
+function logout()
+{
+ store.delete("account");
+ ipcEmit("set-account", false);
+ endSession();
+};
+
+function initAccount()
+{
+ ipcMain.handle("login", login);
+ ipcMain.on("logout", logout);
+
+ const account = store.get("account");
+ if (account) launchSession(account);
+}
+
+exports.initAccount = initAccount;
diff --git a/src/account.ts b/src/account.ts
deleted file mode 100644
index 581da0e..0000000
--- a/src/account.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-
-import { postAuth, postLogin, postLogout } from "@/api/account";
-import { endSession, launchSession } from "@/session";
-import { getToken, setToken, setProfile, getProfile, clearStore } from "./store";
-import { parseAuthRes } from "./auth";
-import { ipcEmit } from "@/composables/useEmitter";
-
-export const accountAuth = async (): Promise => {
-
- /* attempt to get a login token from the store */
- const token = getToken();
-
- /* try to login with it, returns platform secret and new token on success */
- if (token) {
- try {
-
- const res = await postAuth(token);
-
- const parsed = parseAuthRes(res);
-
- setToken(parsed.token)
- setProfile(parsed.profile);
-
- return {
- profile: parsed.profile,
- token: parsed.token
- };
-
- } catch(e) {
- console.log('[ACCOUNT]', e);
- clearStore();
- throw(new Error('Failed to authenticate.'));
-
- }
- } else {
- throw(new Error('Unable to authenticate.'));
- }
-};
-
-export const accountLogin: IpcHandlerCallback = async (payload) => {
- const account = payload as AccountCredentials;
- try {
-
- // attempt login with email password
- const res = await postLogin(account.email, account.password);
- const parsed = parseAuthRes(res);
-
- // save jwt token and profile
- setToken(parsed.token);
- setProfile(parsed.profile);
-
- // launch session
- launchSession(parsed.token);
-
- // return profile to renderer
- return parsed.profile;
-
- } catch(e) {
- clearStore();
- throw e;
- }
-}
-
-
-export const accountLogout = async (): Promise => {
-
- try {
- // post logout to backend
- await postLogout();
-
- // remove key and crimataId
- clearStore();
-
- // kill crimata platform session
- endSession();
-
- return;
-
- } catch(e) {
- console.log('[ACCOUNT]', e);
- return (new Error('Failed to logout. Please try again.'));
- }
-
-}
-
-export const updateAppState = (): void => {
-
- const profile = getProfile();
-
- ipcEmit("set-profile", profile);
-
- // ipcEmit('messages') etc
-
-}
-
diff --git a/src/api.js b/src/api.js
new file mode 100644
index 0000000..89d617e
--- /dev/null
+++ b/src/api.js
@@ -0,0 +1,19 @@
+const axios = require('axios').default;
+
+const config = require("./config");
+
+const baseUrl = config.BUSINESS_URL + config.BUSINESS_PREFIX;
+
+async function postLogin(email, password)
+{
+ try {
+ const res = await axios.post(baseUrl + "/account/login", {
+ email: email, password: password
+ });
+ return res.data;
+ } catch (e) {
+ return false;
+ }
+}
+
+exports.postLogin = postLogin;
\ No newline at end of file
diff --git a/src/api/account.ts b/src/api/account.ts
deleted file mode 100644
index 45baca2..0000000
--- a/src/api/account.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-
-import useHttp from "@/composables/useHttp";
-import axios from "axios";
-import {config} from "@/config";
-
-const { post } = useHttp();
-
-export const postAuth = async (token: string) => (
- await axios({
- url: config.BUSINESS_URL + config.BUSINESS_PREFIX + '/account/authenticate',
- headers: {
- Cookie: `crimataCookie=${token}`
- },
- method: 'POST',
- })
-);
-
-
-export const postLogin = async (email: string, password: string) => (
- await post('/account/login', { email, password })
-);
-
-
-export const postLogout =
- async (): Promise => (await post('/account/logout'));
-
-
-
-
-
-
diff --git a/src/assets/icon.icns b/src/assets/icon.icns
new file mode 100644
index 0000000..b173533
Binary files /dev/null and b/src/assets/icon.icns differ
diff --git a/src/assets/tray/000.png b/src/assets/tray/000.png
new file mode 100644
index 0000000..e6d5d32
Binary files /dev/null and b/src/assets/tray/000.png differ
diff --git a/src/assets/tray/000@2x.png b/src/assets/tray/000@2x.png
new file mode 100644
index 0000000..6d61d7f
Binary files /dev/null and b/src/assets/tray/000@2x.png differ
diff --git a/src/assets/tray/001.png b/src/assets/tray/001.png
new file mode 100644
index 0000000..8d65b38
Binary files /dev/null and b/src/assets/tray/001.png differ
diff --git a/src/assets/tray/001@2x.png b/src/assets/tray/001@2x.png
new file mode 100644
index 0000000..b7f0e2c
Binary files /dev/null and b/src/assets/tray/001@2x.png differ
diff --git a/src/assets/tray/010.png b/src/assets/tray/010.png
new file mode 100644
index 0000000..bc5718c
Binary files /dev/null and b/src/assets/tray/010.png differ
diff --git a/src/assets/tray/010@2x.png b/src/assets/tray/010@2x.png
new file mode 100644
index 0000000..6b97193
Binary files /dev/null and b/src/assets/tray/010@2x.png differ
diff --git a/src/assets/tray/011.png b/src/assets/tray/011.png
new file mode 100644
index 0000000..c2f8612
Binary files /dev/null and b/src/assets/tray/011.png differ
diff --git a/src/assets/tray/011@2x.png b/src/assets/tray/011@2x.png
new file mode 100644
index 0000000..befcd5f
Binary files /dev/null and b/src/assets/tray/011@2x.png differ
diff --git a/src/assets/tray/100.png b/src/assets/tray/100.png
new file mode 100644
index 0000000..99df7df
Binary files /dev/null and b/src/assets/tray/100.png differ
diff --git a/src/assets/tray/100@2x.png b/src/assets/tray/100@2x.png
new file mode 100644
index 0000000..2d26144
Binary files /dev/null and b/src/assets/tray/100@2x.png differ
diff --git a/src/assets/tray/101.png b/src/assets/tray/101.png
new file mode 100644
index 0000000..523bc93
Binary files /dev/null and b/src/assets/tray/101.png differ
diff --git a/src/assets/tray/101@2x.png b/src/assets/tray/101@2x.png
new file mode 100644
index 0000000..91a15be
Binary files /dev/null and b/src/assets/tray/101@2x.png differ
diff --git a/src/assets/tray/110.png b/src/assets/tray/110.png
new file mode 100644
index 0000000..ddd2524
Binary files /dev/null and b/src/assets/tray/110.png differ
diff --git a/src/assets/tray/110@2x.png b/src/assets/tray/110@2x.png
new file mode 100644
index 0000000..fd073dd
Binary files /dev/null and b/src/assets/tray/110@2x.png differ
diff --git a/src/assets/tray/111.png b/src/assets/tray/111.png
new file mode 100644
index 0000000..d2dd686
Binary files /dev/null and b/src/assets/tray/111.png differ
diff --git a/src/assets/tray/111@2x.png b/src/assets/tray/111@2x.png
new file mode 100644
index 0000000..2bc77fd
Binary files /dev/null and b/src/assets/tray/111@2x.png differ
diff --git a/src/audio.js b/src/audio.js
new file mode 100644
index 0000000..3736ee9
--- /dev/null
+++ b/src/audio.js
@@ -0,0 +1,137 @@
+const nodeAudio = require("@crimata/nodeaudio");
+const { globalShortcut, ipcMain } = require("electron");
+
+const { sendMessage } = require("./io");
+const { updateTray } = require("./tray");
+const { encode, decode } = require("./codec");
+const { backgroundMitt, ipcEmit } = require("./utils/emitter");
+
+let inputDevice;
+let outputDevice;
+
+let setWriteId;
+let setStreamsId;
+
+let autoStopId; /* keep track of recording time */
+
+let playbackId; /* UID of the message being played */
+
+const streamState = { rec: false, pb: false };
+
+const /** @type {Int16Array[]} */ chunks = [];
+
+backgroundMitt.on("data", (int16Arr) => {
+ if (streamState.rec) chunks.push(int16Arr);
+});
+
+backgroundMitt.on("write", (int16Arr) => {
+ clearTimeout(setWriteId);
+ setWriteId = setTimeout(setPlaybackStatus.prototype.bind(null, false), 500);
+});
+
+function setStreams()
+{
+ const defaultInput = nodeAudio.core.GetDefaultInputDevice();
+ const defaultOutput = nodeAudio.core.GetDefaultOutputDevice();
+
+ if (inputDevice !== defaultInput)
+ {
+ inputDevice = defaultInput;
+ nodeAudio.core.CloseInputStream(inputDevice);
+ nodeAudio.core.OpenInputStream(inputDevice);
+ }
+
+ if (outputDevice !== defaultOutput)
+ {
+ outputDevice = defaultOutput;
+ nodeAudio.core.CloseOutputStream(outputDevice);
+ nodeAudio.core.OpenOutputStream(outputDevice);
+ }
+}
+
+function startRecording()
+{
+ setRecordingStatus(true);
+
+ /* 15s recording time limit */
+ autoStopId = setTimeout(stopRecording, 15000);
+}
+
+function stopRecording()
+{
+ if (autoStopId)
+ {
+ clearTimeout(autoStopId);
+ }
+
+ setRecordingStatus(false);
+
+ sendMessage({
+ category: "audio/L16",
+ text: null,
+ blob: encode(nodeAudio.utils.mergeChunks(chunks).buffer)
+ });
+
+ chunks.length = 0;
+}
+
+function initAudio()
+{
+ nodeAudio.core.Initialize(backgroundMitt.emit.bind(backgroundMitt));
+ setStreamsId = setInterval(setStreams, 2000);
+
+ const res = globalShortcut.register('CommandOrControl+Return', () => {
+ streamState.rec ? stopRecording() : startRecording();
+ });
+
+ if (!res) throw new Error("Failed to register recording shortcut");
+}
+
+function playback(base64String, id)
+{
+ /* terminate any current playback */
+ nodeAudio.core.CancelPlayback();
+ ipcEmit("playback", playbackId, false);
+
+ playbackId = id;
+ setPlaybackStatus(true);
+ nodeAudio.core.WriteToOutputStream(decode(base64String));
+}
+
+function terminateAudio()
+{
+ globalShortcut.unregisterAll();
+
+ /* Only terminate PA if initialized */
+ if (setStreamsId)
+ {
+ clearInterval(setStreamsId);
+ nodeAudio.core.Terminate();
+ }
+}
+
+function setRecordingStatus(status)
+{
+ streamState.rec = status;
+ ipcEmit("record", status);
+ updateTray("recording", streamState.rec);
+}
+
+function setPlaybackStatus(status)
+{
+ console.log("Setting playback status: ", status);
+
+ streamState.pb = status;
+ ipcEmit("playback", playbackId, status);
+ updateTray("playback", status);
+}
+
+exports.initAudio = initAudio;
+exports.terminateAudio = terminateAudio;
+exports.playback = playback;
+exports.streamState = streamState;
+
+
+// setWriteId = setTimeout(() => {
+// setPlaybackStatus(false);
+// }, 500);
diff --git a/src/audio.ts b/src/audio.ts
deleted file mode 100644
index 7ae2562..0000000
--- a/src/audio.ts
+++ /dev/null
@@ -1,187 +0,0 @@
-/* eslint @typescript-eslint/no-var-requires: "off" */
-
-"use strict";
-
-// where the audio goes
-let buffer: ArrayBuffer[] = [];
-
-// place audio data in buffer
-export const collect: IpcListenerCallback = (chunk) => {
- if (chunk) buffer.push(chunk);
-}
-
-// return audio and clear buffer
-export const flush = async () => {
- const bufferCopy = buffer;
- buffer = [];
- return bufferCopy;
-}
-
-// import { backgroundMitt } from '@/modules/emitter';
-// const portAudio = require('naudiodon');
-
-// // Audio in and out stream objects.
-// let ai: typeof portAudio.AudioIO | boolean = false;
-// let ao: typeof portAudio.AudioIO | boolean = false;
-
-// // Whether activly recording.
-// let record = false;
-
-// const audioContainer = {
-// input: '',
-// }
-
-// const audioOptions = {
-// channelCount: 1,
-// sampleFormat: 16,
-// sampleRate: 16000,
-// deviceId: -1,
-// closeOnError: false,
-// }
-
-// export const toggleRecord = (): void => { record = !record };
-
-
-// export const fetchAudioInput = (): Promise => (
-
-// new Promise((resolve, reject) => {
-
-// try {
-// resolve(audioContainer.input);
-// toggleRecord();
-// } catch (e) {
-// reject(new Error('Failed to fetch the audio.'))
-// }
-
-// })
-// )
-
-
-// // Main audio function run by run.ts module.
-// export function initAudioIO(): void {
-// console.log("AUDIO:Starting io streams.")
-
-// if (!ai) {
-
-// // Initialize and start input stream.
-// ai = new portAudio.AudioIO({ inOptions: audioOptions });
-// ai.setEncoding("hex");
-// ai.start();
-
-// // On each data chunk...
-// ai.on('data', (chunk: string) => {
-
-// // If recording, we capture the data.
-// if (record) {
-// console.log('AUDIO:Recording...')
-// audioContainer.input += chunk;
-// }
-
-// // Else, we don't capture and also clear audioContainer.
-// else {
-// if (audioContainer.input.length) {
-// audioContainer.input = "";
-// }
-// }
-
-// });
-// }
-
-// if (!ao) {
-
-// // Initialize and start input stream.
-// ao = new portAudio.AudioIO({ outOptions: audioOptions });
-// ao.start();
-
-// }
-// }
-
-
-// // ---Audio playback--------------------------------------------
-
-// // Split Buffer into an array of len-sized Buffers.
-// function bufSplit(buf: Buffer, len: number): Array {
-// const chunks = [];
-// let i = 0;
-// let L = len;
-
-// while(i < buf.byteLength) {
-// chunks.push(buf.slice(i, L));
-// i = L;
-// L += len;
-// }
-
-// return chunks;
-// }
-
-// // Audio playback.
-// export function play(input: string): void {
-
-// // Format the audio.
-// const audio = bufSplit(
-// Buffer.from(input as string, 'hex'),
-// 8192
-// );
-
-// // Called on end of write.
-// const callback = () => {
-
-// // We stop audio playback anim.
-// backgroundMitt.emit('ipc-renderer', {
-// endpoint: 'stop-playback-anim'
-// });
-
-// }
-
-// write();
-
-// // Iterate through audio array and write buffers to portAudio writable.
-// function write() {
-// let chunk: Buffer;
-// let ok = true;
-// let i = 0;
-
-// do {
-// chunk = audio[i];
-// if (i === audio.length - 1) {
-// // write last chunk.
-// ao.write(chunk, null, callback);
-// } else {
-// // check for backpreassure.
-// ok = ao.write(chunk, null);
-// }
-// i++;
-// } while (i < audio.length && ok);
-
-// if (i < audio.length) {
-// // Had to stop early!
-// // Write some more once it drains.
-// ao.once('drain', write);
-// }
-// }
-// }
-
-// // -------------------------------------------------------------
-
-// // Get's called on window close.
-// export async function stopStream() {
-// console.log("AUDIO:Stopping audio stream.")
-// if (ai) {
-// try {
-// await ai.quit()
-// } catch(e){
-// console.log('AUDIO: Failed to shutdown audio input.');
-// throw e;
-// }
-// }
-// if (ao) {
-// try {
-// await ao.quit()
-// } catch(e){
-// console.log('AUDIO: Failed to shutdown audio output.');
-// throw e;
-// }
-// }
-// }
-
-
diff --git a/src/auth.ts b/src/auth.ts
deleted file mode 100644
index 14ed36a..0000000
--- a/src/auth.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-
-export const parseAuthRes = (authRes: any) => {
- const token = authRes.headers['set-cookie'][0].split(";")[0].split("=")[1] as string;
- const profile = authRes.data as Profile;
- return {
- token,
- profile
- }
-};
-
-
-
-
diff --git a/src/codec.js b/src/codec.js
new file mode 100644
index 0000000..3a9a8bf
--- /dev/null
+++ b/src/codec.js
@@ -0,0 +1,13 @@
+const { ipcMain } = require("electron");
+const { encode, decode } = require("base64-arraybuffer");
+
+ipcMain.handle("encode", (_e, arrayBuffer) => {
+ return encode(arrayBuffer);
+});
+
+ipcMain.handle("decode", (_e, b64string) => {
+ return decode(b64string);
+});
+
+exports.encode = encode;
+exports.decode = decode;
\ No newline at end of file
diff --git a/src/composables/autoUpdate.ts b/src/composables/autoUpdate.ts
deleted file mode 100644
index 1a6b780..0000000
--- a/src/composables/autoUpdate.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-const { autoUpdater } = require('electron-updater');
-
-let win: boolean;
-
-// Listen for window creation.
-backgroundMitt.on('window-active', (state: boolean) => {
- win = state;
-});
-
-// Auto updating.
-autoUpdater.requestHeaders = { 'PRIVATE-TOKEN': 'mvvgWYwWnot4bisiQMh_' }
-
-autoUpdater.on('update-available', (info: any) => {
- console.log(`Update available: ${info.version}`)
-})
-
-autoUpdater.on('update-downloaded', (info: any) => {
-
- const updateDialog = {
- type: 'info',
- buttons: ['Restart', 'Later'],
- title: 'Application Update',
- message: info.version,
- detail: 'A new version has been downloaded. Restart the application to apply the updates.'
- }
-
- dialog.showMessageBox(updateDialog).then((returnValue) => {
- if (returnValue.response === 0) autoUpdater.quitAndInstall()
- })
-
-})
\ No newline at end of file
diff --git a/src/composables/useEmitter.ts b/src/composables/useEmitter.ts
deleted file mode 100644
index f95f328..0000000
--- a/src/composables/useEmitter.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-
-// Backend emitter
-//
-const EventEmitter = require('events');
-class BackgroundMitt extends EventEmitter { }
-
-export const backgroundMitt = new BackgroundMitt();
-
-export const ipcEmit = (channel: string, payload: T) => {
- backgroundMitt.emit('ipc-renderer', {
- channel,
- payload
- });
-};
-
-
diff --git a/src/composables/useHttp.ts b/src/composables/useHttp.ts
deleted file mode 100644
index 6b9ee56..0000000
--- a/src/composables/useHttp.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-
-import axios, { AxiosRequestConfig } from 'axios';
-import {config} from "@/config";
-
-const baseURL = config.BUSINESS_URL + config.BUSINESS_PREFIX;
-
-interface Request {
- endpoint: string;
- query?: Record;
- config?: Record;
-}
-
-const makeQuery = (reqQuery: Record) => {
-
- let result = '';
-
- result = '?' + Object.entries(reqQuery)
- .map(([ key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
- .join('&')
-
- return result;
-};
-
-
-export default function useHttp() {
-
- const api = axios.create({
- baseURL,
- withCredentials: true,
- });
-
-
- const post = async (endpoint: string, payload?: Record): Promise => (
- await api.post(endpoint, payload)
- )
-
-
- const get = async (req: Request) => {
-
- if (req.query) {
- req.endpoint += makeQuery(req.query);
- }
-
- const res = await api.get(req.endpoint, req.config);
- return res;
- };
-
- return {
- get, post
- }
-}
diff --git a/src/composables/useIpcMain.ts b/src/composables/useIpcMain.ts
deleted file mode 100644
index ebfc4bc..0000000
--- a/src/composables/useIpcMain.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-
-import { ipcMain, IpcMainInvokeEvent, IpcMainEvent } from "electron";
-
-export class IpcHandler implements IIpcHandler {
-
- readonly channel: string;
-
- readonly _handlerCallback: IpcHandlerCallback;
-
- constructor(options: {
- channel: string;
- handlerCallback: IpcHandlerCallback;
- }) {
- this.channel = options.channel;
- this._handlerCallback = options.handlerCallback;
- }
-
- handle() {
- this.remove();
- ipcMain.handle(this.channel, this._onInvoke);
- }
-
- remove() {
- ipcMain.removeHandler(this.channel);
- }
-
- private _onInvoke = (_e: IpcMainInvokeEvent, payload?: string | null): Promise => {
-
- return new Promise(async (resolve, reject) => {
-
- console.log(`[IPC] Handle:${this.channel}`);
-
- try {
-
- const params = payload ? JSON.parse(payload) : null;
-
- const res = await this._handlerCallback(params);
-
- resolve(res as unknown as ReturnType);
-
- } catch(e) {
- console.log(`[IPC] Error:${this.channel}`);
- reject(e);
- }
- });
- }
-
-}
-
-
-export class IpcListener implements IIpcListener {
-
- readonly channel: string;
-
- readonly _listenerCallback: IpcListenerCallback;
-
- constructor(options: {
- channel: string;
- listenerCallback: IpcListenerCallback;
- }) {
- this.channel = options.channel;
- this._listenerCallback = options.listenerCallback;
- }
-
- listen() {
- this.remove();
- ipcMain.on(this.channel, this._onPost);
- }
-
- remove() {
- ipcMain.removeAllListeners(this.channel);
- }
-
- private _onPost = (_e: IpcMainEvent, payload?: string | null): void => {
-
- console.log(`[IPC] Post: ${this.channel}`);
-
- const params = payload ? JSON.parse(payload) : null;
- this._listenerCallback(params);
- }
-
-}
diff --git a/src/composables/useMessageCanvas.ts b/src/composables/useMessageCanvas.ts
deleted file mode 100644
index c85f7ed..0000000
--- a/src/composables/useMessageCanvas.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-export default class Canvas {
-
- messages: Message[];
-
- /* seed canvas with messages on init */
- constructor(messages: Message[]) {
- this.messages = messages;
- ipcEmit("seed-view", this.messages);
- }
-
- /* add a new message to the canvas */
- add(message: Message) {
- this.messages.push(message);
- ipcEmit("update-view", message);
- }
-
- /* update an existing message */
- update(message: Message) {
-
- /* get the target message */
- let target_message = this.messages.filter((m: Message) => {
- return m.uid = message.uid;
- })[0];
-
- /* replace the target message */
- if (target_message) {
- target_message = message;
- ipcEmit("update-view", message);
- }
-
- }
-
-}
diff --git a/src/composables/useSaveToJSON.ts b/src/composables/useSaveToJSON.ts
deleted file mode 100644
index 06ab4b9..0000000
--- a/src/composables/useSaveToJSON.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-
-import {config} from "@/config";
-import fs from 'fs';
-
-export const saveToJson = (fileName: string, data: any) => {
-
- fs.writeFile(config.configPath + fileName, JSON.stringify(data), (err) => {
- if (err) {
- console.log("Error when saving to json.")
- }
- })
-
-}
diff --git a/src/composables/useWebsockets.ts b/src/composables/useWebsockets.ts
deleted file mode 100644
index d1cfc02..0000000
--- a/src/composables/useWebsockets.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-
-"use strict";
-
-import WebSocket from 'ws';
-
-
-const _connectionCheckTimeout = 4000;
-const _reconnectTimeout = 1000;
-let _connectionCheckInterval: ReturnType;
-
-
-export default function useWebSockets(
- messageCallback: (message: string) => void,
- connectionStatusCallback: (alive: boolean) => void,
-) {
-
- let socket: WebSocket;
-
- const send = async (data: Record): Promise => {
- return new Promise((resolve, reject) => {
- if (socket) {
- if (socket.readyState === WebSocket.OPEN) {
- socket.send(JSON.stringify(data));
- resolve(true);
- }
- }
- reject(false);
- });
- }
-
- const connect = (socketUrl: string, secret: string) => {
-
- // avoid setting multiple interval;
- if (_connectionCheckInterval) clearInterval(_connectionCheckInterval);
-
- /* create a new socket */
- socket = new WebSocket(socketUrl);
-
- /* add event listeners */
- socket.on("open", () => {
-
- socket.send(JSON.stringify({key: secret}));
-
- // ping server
- _connectionCheckInterval = setInterval(() => {
-
- socket.ping(null, true, (e: Error) => {
- if (e) {
- socket.close();
- connectionStatusCallback(false);
- setTimeout(() => connect(socketUrl, secret), _reconnectTimeout);
- }
- });
-
- }, _connectionCheckTimeout);
-
- });
-
- socket.on("message", (event: WebSocket.MessageEvent) => {
- console.log("message received", event);
- messageCallback(event.toString())
- });
-
- socket.on("close", (event: WebSocket.CloseEvent) => {
- connectionStatusCallback(false);
- clearInterval(_connectionCheckInterval);
- if (!event.wasClean) {
- setTimeout(() => connect(socketUrl, secret), _reconnectTimeout);
- }
-
- });
-
- socket.on("pong", () => connectionStatusCallback(true));
-
- }
-
- const close = () => {
- if (socket) {
- socket.close();
- }
- }
-
- return {
- connect,
- send,
- close
- };
-
-}
diff --git a/src/config.ts b/src/config.js
similarity index 79%
rename from src/config.ts
rename to src/config.js
index 855b1b2..adf5e22 100644
--- a/src/config.ts
+++ b/src/config.js
@@ -1,5 +1,4 @@
-
-import { app } from "electron";
+const { app } = require("electron");
const env = process.env;
@@ -9,9 +8,9 @@ const PLATFORM_IP = env.PLATFORM_IP || 'http://127.0.0.1';
const BUSINESS_PORT = env.BUSINESS_PORT || 3000;
const BUSINESS_IP = env.BUSINESS_IP || 'http://127.0.0.1';
-export const config = {
+module.exports = {
PLATFORM_URL: `${PLATFORM_IP}:${PLATFORM_PORT}`,
BUSINESS_URL: `${BUSINESS_IP}:${BUSINESS_PORT}`,
BUSINESS_PREFIX: '/api',
- configPath: app.getPath('userData')
-}
+ configPath: app.getPath('userData'),
+}
\ No newline at end of file
diff --git a/src/init.ts b/src/init.ts
deleted file mode 100644
index 9a0fdf6..0000000
--- a/src/init.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Entry point for Crimata electron app.
- * "Look on my Works, ye Mighty, and despair!"
- */
-
-"use strict";
-
-import { app, protocol } from "electron";
-import createWindow from "./window";
-import main from "./main";
-import { backgroundMitt } from '@/composables/useEmitter';
-
-console.log('Starting Crimata electron app.');
-
-// Scheme must be registered before the app is ready
-protocol.registerSchemesAsPrivileged([
- { scheme: "app", privileges: { secure: true, standard: true } }
-]);
-
-const isDev = require('electron-is-dev');
-
-let win: boolean;
-
-// Listen for window creation.
-backgroundMitt.on('window-active', (state: boolean) => {
- win = state;
-});
-
-/* Start main process on ready */
-app.on("ready", async () => {
- await main();
-});
-
-// Must keep to ensure app doesn't quit on close.
-app.on("before-quit", async () => {
-});
-
-// Must keep to ensure app doesn't quit on close.
-app.on("window-all-closed", () => {
-});
-
-// When user clicks app icon (re-open)
-app.on("activate", () => {
- if (!win) createWindow();
-});
-
-// Exit cleanly on request from parent process in development mode.
-if (isDev) {
- process.on("SIGTERM", () => {
- app.quit();
- });
-}
diff --git a/src/io.js b/src/io.js
new file mode 100644
index 0000000..a269d49
--- /dev/null
+++ b/src/io.js
@@ -0,0 +1,80 @@
+const WebSocket = require("ws");
+const { ipcMain } = require("electron");
+
+const config = require("./config");
+const { updateTray } = require("./tray");
+const { backgroundMitt, ipcEmit } = require("./utils/emitter");
+
+let connection = null;
+
+let pingId;
+let reconnectId;
+
+function connectToPlatform(account)
+{
+ if (pingId) clearInterval(pingId);
+
+ connection = new WebSocket(`${config.PLATFORM_URL}/${account}`)
+
+ .on("open", () => pingId = setInterval(() => connection.ping(null, true), 1000))
+
+ .on("pong", () => setConnectionStatus(0))
+
+ .on("error", () => {}) /** keep silent on error */
+
+ .on("message", (payload) => backgroundMitt.emit("message", JSON.parse(payload)))
+
+ .on("close", (code, reason) => {
+ setConnectionStatus(1);
+ if (reason !== "logout") {
+ reconnectId = setTimeout(() => connectToPlatform(account), 500);
+ }
+ });
+}
+
+function sendMessage(message)
+{
+ if (connection.readyState === WebSocket.OPEN) {
+ connection.send(JSON.stringify(message));
+ } else console.log("Failed to send message");
+}
+
+function disconnectFromPlatform()
+{
+ clearTimeout(reconnectId);
+ connection.close(1000, "logout");
+}
+
+function setConnectionStatus(status)
+{
+ updateTray("disconnect", status);
+ ipcEmit("ws-status", status);
+}
+
+ipcMain.on("message", (_e, message) => sendMessage(message));
+
+exports.connectToPlatform = connectToPlatform;
+exports.sendMessage = sendMessage;
+exports.disconnectFromPlatform = disconnectFromPlatform;
+
+
+
+/* ------------- Test Messages------------- */
+
+
+
+setTimeout(() => {
+
+ // sendMessage({
+ // category: "text/plain",
+ // text: "show contacts",
+ // blob: null
+ // })
+
+ sendMessage({
+ category: "text/plain",
+ text: "add contact John Smith, john.smith97@gmail.com",
+ blob: null
+ })
+
+}, 2000);
diff --git a/src/ipc/handlers.ts b/src/ipc/handlers.ts
deleted file mode 100644
index 5529662..0000000
--- a/src/ipc/handlers.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-
-"use strict";
-
-import { accountLogin, accountLogout, accountProfile } from "@/account";
-import { IpcHandler } from "@/composables/useIpcMain";
-import { flush } from "@/audio";
-
-
-const LOGIN_CHANNEL = "invoke-account-login";
-const LOGOUT_CHANNEL = "invoke-account-logout";
-const GET_AUDIO_CHANNEL = "invoke-audio-flush";
-
-export const loginHandler = new IpcHandler({
- channel: LOGIN_CHANNEL,
- handlerCallback: accountLogin
-});
-
-export const logoutHandler = new IpcHandler({
- channel: LOGOUT_CHANNEL,
- handlerCallback: accountLogout
-});
-
-export const getAudioHandler = new IpcHandler({
- channel: GET_AUDIO_CHANNEL,
- handlerCallback: flush
-});
-
-
diff --git a/src/ipc/index.ts b/src/ipc/index.ts
deleted file mode 100644
index e6eb90a..0000000
--- a/src/ipc/index.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-
-"use strict";
-
-import * as handlers from "./handlers";
-import * as listeners from "./listeners";
-
-const ipcHandlers: IPCHandlers = {};
-const ipcListeners: IPCListeners = {};
-
-const _initHandlers = (): void => {
- for (const [key, handler] of Object.entries(handlers)) {
- if (!(key in ipcHandlers)) {
- ipcHandlers[key] = handler;
- handler.handle();
- }
- }
-};
-
-const _initListeners = (): void => {
- for (const [key, listener] of Object.entries(listeners)) {
- if (!(key in ipcListeners)) {
- ipcListeners[key] = listener;
- listener.listen();
- }
- }
-};
-
-export default function initIpcMain(): void {
- _initHandlers();
- _initListeners();
-}
-
-
diff --git a/src/ipc/listeners.ts b/src/ipc/listeners.ts
deleted file mode 100644
index 8ef5d45..0000000
--- a/src/ipc/listeners.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-
-import { IpcListener } from "@/composables/useIpcMain"
-import { sendMessage } from '@/session';
-import { collect } from "@/audio";
-import { updateAppState } from "@/account";
-
-const CLIENT_MESSAGE_CHANNEL = "post-session-send"
-const GET_AUDIO_CHANNEL = "post-audio-collect";
-const APP_MOUNT_CHANNEL = "post-app-mount";
-
-export const messageListener = new IpcListener({
- channel: CLIENT_MESSAGE_CHANNEL,
- listenerCallback: sendMessage
-});
-
-export const audioChunkListener = new IpcListener({
- channel: GET_AUDIO_CHANNEL,
- listenerCallback: collect
-});
-
-export const appMountListener = new IpcListener({
- channel: APP_MOUNT_CHANNEL,
- listenerCallback: updateAppState
-});
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..841579e
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,29 @@
+const { app, protocol, ipcMain, nativeTheme } = require("electron");
+
+const store = require("./utils/store");
+
+const { initTray } = require("./tray");
+const { postLogin } = require("./api");
+const { createWin } = require("./window");
+const { initAccount } = require("./account");
+const { terminateAudio } = require("./audio");
+
+// Assert a light theme
+nativeTheme.themeSource = "light";
+
+app.on("ready", () =>
+{
+ initTray();
+
+ createWin();
+
+ initAccount();
+});
+
+// app.on("will-quit", terminateAudio);
+
+// When user clicks app icon (re-open)
+app.on("activate", createWin);
+
+// Prevents app from quitting on window close event
+app.on('window-all-closed', (e) => e.preventDefault());
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
deleted file mode 100644
index a360835..0000000
--- a/src/main.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Where the background logic really begins, gets called by app.onReady().
- *
- * Handles authentication. If profile is set, we launch a session, which consis
- * of opening a connection with the platform, initializing the audio streams.
- *
- * The session is primarily an interface between the frontend and the platform,
- * relaying messages from one to the other.
- *
- */
-
-import initIpcMain from "@/ipc/index";
-import { accountAuth, updateAppState } from "./account";
-import { launchSession } from "./session";
-import createWindow from "./window";
-
-let authState: AuthState | null;
-
-export default async function main() {
-
- /* initiate controls for frontend to use when needed */
- initIpcMain();
-
- /* launch browser window */
- await createWindow();
-
- try {
- authState = await accountAuth() as AuthState;
- } catch(e) {
- console.log('AUTH:', e);
- authState = null;
- } finally {
- if (authState) {
- launchSession(authState.token as string);
- }
- updateAppState();
- }
-
-}
diff --git a/src/preview.html b/src/preview.html
new file mode 100644
index 0000000..8c8fc48
--- /dev/null
+++ b/src/preview.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/render/App.vue b/src/render/App.vue
deleted file mode 100644
index 686591b..0000000
--- a/src/render/App.vue
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/render/assets/connectLogo.svg b/src/render/assets/connectLogo.svg
new file mode 100644
index 0000000..7a390a4
--- /dev/null
+++ b/src/render/assets/connectLogo.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/render/assets/settingsIcon.svg b/src/render/assets/settingsIcon.svg
new file mode 100644
index 0000000..25399f5
--- /dev/null
+++ b/src/render/assets/settingsIcon.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/render/components/app.js b/src/render/components/app.js
new file mode 100644
index 0000000..08909a6
--- /dev/null
+++ b/src/render/components/app.js
@@ -0,0 +1,42 @@
+import Splash from "./splash.js";
+import Messenger from "./messenger.js";
+import Login from "./login.js";
+
+const account = Vue.ref(null);
+
+const App =
+{
+ components: {
+ Splash,
+ Messenger,
+ Login
+ },
+
+ setup()
+ {
+ return { account };
+ },
+
+ template: `
+
+
+
+
+
+
+
+
+
+ `
+}
+
+window.mainApi.on("set-account", (account_) => {
+ console.log("setting-account");
+ account.value = account_;
+});
+
+export default App;
+export { account };
+
+// Is called when window is about to close or reload
+window.onbeforeunload = () => console.log("beforeUnload");
\ No newline at end of file
diff --git a/src/render/components/bubble.js b/src/render/components/bubble.js
new file mode 100644
index 0000000..16f7983
--- /dev/null
+++ b/src/render/components/bubble.js
@@ -0,0 +1,36 @@
+const Bubble =
+{
+ props: ["category", "text", "blob", "modifier", "child"],
+
+ setup(props)
+ {
+ const getUrl = () => {
+ return `data:${props.category};base64,${props.blob}`;
+ }
+
+ Vue.onMounted(() => {
+ document.getElementById("messenger").dispatchEvent(new CustomEvent('adjust-scroll'));
+ });
+
+ return { getUrl };
+ },
+
+ template: `
+
+
+
{{ text }}
+
+
{{ text }}
+
+
+
+
+
+
{{ text }}
+
+
`
+};
+
+export default Bubble;
+
+// TODO: should include other styling/actions for audio bubbles
\ No newline at end of file
diff --git a/src/render/components/bubble.vue b/src/render/components/bubble.vue
deleted file mode 100644
index 982cef3..0000000
--- a/src/render/components/bubble.vue
+++ /dev/null
@@ -1,331 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{ context }}
-
-
-
-
-
-
-
-
-
-
diff --git a/src/render/components/context.js b/src/render/components/context.js
new file mode 100644
index 0000000..b6879ae
--- /dev/null
+++ b/src/render/components/context.js
@@ -0,0 +1,38 @@
+
+const Context =
+{
+ props: ["modifier", "context", "avatar", "id"],
+
+ setup(props) {
+ const playback = Vue.ref(false);
+
+ Vue.onMounted(() => {
+ window.mainApi.on("playback", (id, status) => {
+ if (id === props.id) {
+ playback.value = status;
+ }
+ });
+ });
+
+ return { playback };
+ },
+
+ template: `
+
+
+
+
+
+
+
+
+ {{ context }}
+
+ `
+}
+
+export default Context;
diff --git a/src/render/components/control/draggify.js b/src/render/components/control/draggify.js
new file mode 100644
index 0000000..f85b930
--- /dev/null
+++ b/src/render/components/control/draggify.js
@@ -0,0 +1,198 @@
+const saveLocation = "input_item_position";
+const defaultPosition = { x: 15, y: window.innerHeight - 300 };
+
+//---Dragabble Helper Funcs--------------------------------------
+
+// Calculate distance to nearest side.
+function calcSideProximity (elementX, elementLength, winW) {
+
+ // Calc right short.
+ let short = winW - elementX - elementLength;
+
+ // See if it's left short.
+ if (elementX + 20 < winW / 2) {
+ short = elementX
+ }
+
+ return short
+}
+
+// Update elementX or elementY value on window resize
+function calcPosition (elementPosition, elementLength, percent, short, win) {
+
+ // Is it close to the right/bottom side?
+ if (percent > 0.75) {
+ elementPosition = win - short - elementLength;
+ }
+
+ // Is it not close to a side?
+ if (percent < 0.75 && percent > 0.25) {
+ elementPosition = win * percent
+ }
+
+ return elementPosition
+}
+
+function draggify(elementId, margin) {
+
+ let element;
+
+ /* only compatible with elements having equal width and height */
+ let elementLength;
+
+ // Cords of inputItem.
+ const elementX = Vue.ref();
+ const elementY = Vue.ref();
+
+ // Position of inputItem on terms of percentage of window.
+ let percentX;
+ let percentY;
+
+ // How close inputItem is to closest X or Y side.
+ let xShort;
+ let yShort;
+
+ // Keep track of window size;
+ let winW = window.innerWidth;
+ let winH = window.innerHeight;
+
+ //---Reposition Anime-----------------------------------------------
+
+ // Move element to target smoothly.
+ const repositionAnime = (xChange, yChange) => {
+ const xStep = xChange / 6000;
+ const yStep = yChange / 6000;
+
+ for (let i = 1; i <= 6000; i++) {
+
+ setTimeout(() => {
+ elementX.value += xStep;
+ elementY.value += yStep;
+ }, 16) // 60fps
+
+ }
+ }
+
+ //---Event Handlers-----------------------------------------------
+
+ // Update the position of inputItem on mouse dragging.
+ const onMouseMove = (e) => {
+ e.preventDefault();
+
+ const inputItemRect = element.getBoundingClientRect();
+ elementX.value = inputItemRect.left + e.movementX;
+ elementY.value = inputItemRect.top + e.movementY;
+ }
+
+ // Add an event listener for dragging.
+ const onMouseDown = (e) => {
+ e.preventDefault();
+ window.addEventListener('mousemove', onMouseMove);
+ window.addEventListener('mouseup', onMouseUp);
+ }
+
+ // Update position references when user is done moving targetEl.
+ const onMouseUp = (e) => {
+ e.preventDefault();
+
+ window.removeEventListener('mousemove', onMouseMove);
+ window.removeEventListener('mouseup', onMouseUp);
+
+ // See if and calculate reposition.
+ let x = 0; // vector change
+ let y = 0;
+
+ if (elementX.value < 0) {
+ x = (elementX.value - margin)*-1
+ }
+
+ if (elementX.value > winW - elementLength) {
+ const b = winW - elementLength - margin;
+ x = (elementX.value - b)*-1
+ }
+
+ // Reposition y
+ if (elementY.value < 0) {
+ y = (elementY.value - margin)*-1
+ }
+
+ if (elementY.value > winH - elementLength) {
+ const d = winH - elementLength - margin;
+ y = (elementY.value - d)*-1
+ }
+
+ // Reposition if needed.
+ if (x !== 0 || y !== 0) repositionAnime(x, y);
+
+ xShort = calcSideProximity(elementX.value, elementLength, winW);
+ yShort = calcSideProximity(elementY.value, elementLength, winH);
+
+ // Update percentages.
+ percentX = elementX.value / winW;
+ percentY = elementY.value / winH;
+
+ // Save position.
+ savePosition();
+ }
+
+ // Update position of targetEl on windowResize.
+ const onWindowResize = (_e) => {
+
+ // Update window dimensions.
+ winW = window.innerWidth;
+ winH = window.innerHeight;
+
+ elementX.value = calcPosition(elementX.value, elementLength, percentX, xShort, winW);
+ elementY.value = calcPosition(elementY.value, elementLength, percentY, yShort, winH);
+
+ savePosition();
+ }
+
+ const savePosition = () => {
+ window.localStorage.setItem(saveLocation, JSON.stringify({
+ x: elementX.value,
+ y: elementY.value
+ }));
+ }
+
+ //---------------------------------------------------------------
+
+ Vue.onMounted(() => {
+
+ element = document.getElementById(elementId);
+
+ elementLength = element.offsetWidth;
+
+ // Initialize the positional references.
+ percentX = elementX.value / window.innerWidth;
+ percentY = elementY.value / window.innerHeight;
+
+ xShort = calcSideProximity(elementX.value, elementLength, window.innerWidth);
+ yShort = calcSideProximity(elementX.value, elementLength, window.innerHeight);
+
+ // Then, we can listen for window resize (and mousedown).
+ element.addEventListener("mousedown", onMouseDown);
+ window.addEventListener('resize', onWindowResize)
+ });
+
+ // remove event listeners on component dismount.
+ Vue.onUnmounted(() => {
+ element.removeEventListener('mousedown', onMouseDown);
+ window.removeEventListener('resize', onWindowResize)
+ window.removeEventListener('mouseup', onMouseUp)
+ window.removeEventListener('mousemove', onMouseMove);
+ });
+
+ // Try loading initPosition, otherwise set default values
+ let initPosition;
+ const rawData = window.localStorage.getItem("saveLocation")
+ rawData ? initPosition = JSON.parse(rawData) : initPosition = defaultPosition;
+
+ elementX.value = initPosition.x;
+ elementY.value = initPosition.y;
+
+ return { elementX, elementY };
+
+}
+
+export default draggify;
diff --git a/src/render/components/control/scroll.js b/src/render/components/control/scroll.js
new file mode 100644
index 0000000..4666ea1
--- /dev/null
+++ b/src/render/components/control/scroll.js
@@ -0,0 +1,24 @@
+let el;
+
+const initScroll = (elementId) => {
+ el = document.getElementById(elementId);
+ el.addEventListener('adjust-scroll', adjustScroll);
+ window.addEventListener('resize', adjustScroll);
+}
+
+const isBottom = () => {
+ if (el) {
+ return el.scrollHeight - el.clientHeight <= el.scrollTop + 1;
+ }
+}
+
+const adjustScroll = () => {
+ if (el) {
+ el.scrollTo({
+ top: el.scrollHeight - el.clientHeight,
+ behavior: 'smooth'
+ });
+ }
+}
+
+export default initScroll;
\ No newline at end of file
diff --git a/src/render/components/control/text.js b/src/render/components/control/text.js
new file mode 100644
index 0000000..626746f
--- /dev/null
+++ b/src/render/components/control/text.js
@@ -0,0 +1,76 @@
+const inputLength = 230;
+
+const metaKeys = [
+ "Tab",
+ "CapsLock",
+ "Shift",
+ "Control",
+ "Alt",
+ "Meta",
+ " ",
+ "ArrowLeft",
+ "ArrowRight",
+ "ArrowUp",
+ "ArrowDown",
+ "Enter",
+ "Backspace",
+ "Escape"
+];
+
+function useText(elementId, left, typing)
+{
+ let el;
+
+ const show = Vue.ref(false);
+ const leftSide = Vue.ref(false);
+
+ const calcSide = () => {
+ window.innerWidth - left.value < inputLength ? leftSide.value = true : leftSide.value = false;
+ }
+
+ /* handle user typing */
+ Vue.onMounted(() => {
+
+ el = document.getElementById(elementId);
+
+ window.addEventListener("keydown", (e) => {
+
+ if (!show.value && !metaKeys.includes(e.key))
+ {
+ show.value = true;
+ }
+ else if (show.value && ((el.value.length === 1 && e.key === "Backspace") || e.key === "Escape"))
+ {
+ show.value = false;
+ }
+
+ if (e.key === "Enter" && el.value)
+ {
+ window.mainApi.send("message", {
+ category: "text/plain",
+ text: el.value,
+ blob: null
+ });
+ show.value = false;
+ }
+ });
+
+ });
+
+ Vue.watch(left, calcSide);
+
+ Vue.watch(show, (c, _p) => {
+ if (c) {
+ el.focus();
+ } else {
+ el.value = "";
+ el.blur();
+ }
+ });
+
+ calcSide();
+
+ return { leftSide, show };
+}
+
+export default useText;
diff --git a/src/render/components/controllers/bubble.control.ts b/src/render/components/controllers/bubble.control.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/src/render/components/controllers/helpers.ts b/src/render/components/controllers/helpers.ts
deleted file mode 100644
index 23976a8..0000000
--- a/src/render/components/controllers/helpers.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { ref } from "vue";
-import anime from "animejs";
-import { v4 as uuidv4 } from 'uuid';
-
-
-export function animateTextInput () {
-
- const side = ref("right");
-
- function show () {
- const t1 = (side.value === "right") ? 50 : -70;
- const t2 = (side.value === "right") ? 110 : -130;
-
- anime({
- targets: '#textInput',
- opacity: [0, 1],
- translateX: [t1, t2],
- scale: [0.3, 1],
- duration: 500,
- easing: 'easeOutExpo',
- })
-
- }
-
- function hide () {
- const t = (side.value === "right") ? 50 : -80;
-
- anime({
- targets: '#textInput',
- opacity: [1, 0],
- translateX: t,
- scale: 0.3,
- duration: 500,
- easing: 'easeOutExpo',
- })
-
- }
-
- function switchSide () {
- const t = (side.value === "right") ? -130 : 110;
-
- anime({
- targets: '#textInput',
- translateX: t,
- duration: 500,
- easing: 'easeOutExpo',
- })
-
- }
-
- return {
- side,
- show,
- hide,
- switchSide
- };
-
-}
-
-export function animateAudioInput () {
-
- function show () {
- anime({
- targets: '#recIcon',
- opacity: [0, 0.75],
- scale: [0.0, 1],
- duration: 250,
- easing: 'linear',
- })
- }
-
- function hide () {
- anime({
- targets: '#recIcon',
- opacity: [0.75, 0],
- scale: [1, 0],
- duration: 250,
- easing: 'linear',
- })
- }
-
- return {
- show,
- hide
- };
-
-}
-
-
-export function newMessage ({
- text=false,
- audio=false,
- context=false,
- uid=uuidv4()
-}) {
- return {
- text: text,
- audio: audio,
- context: context,
- uid: uid
- };
-}
diff --git a/src/render/components/controllers/inputItem.control.audio.ts b/src/render/components/controllers/inputItem.control.audio.ts
deleted file mode 100644
index facf30c..0000000
--- a/src/render/components/controllers/inputItem.control.audio.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { onMounted, onUnmounted, ref, Ref } from "vue";
-import { postMessage } from "@/render/ipc";
-import { newMessage, animateAudioInput } from "./helpers";
-import { invokeReturnAudio, postAudioChunk } from "@/render/ipc";
-
-export default function useAudioInputController (typing: Ref) {
-
- const recording = ref(false);
- let mediaRecorder: MediaRecorder;
-
- const { show, hide } = animateAudioInput();
-
- // initialize audio
- const conf = {audio: true, video: false}
- navigator.mediaDevices.getUserMedia(conf).then((stream: MediaStream) => {
-
- const options = {mimeType: 'audio/webm'};
- mediaRecorder = new MediaRecorder(stream, options);
-
- // post any mew audio to backend
- mediaRecorder.addEventListener('dataavailable', (e: BlobEvent) => {
- e.data.arrayBuffer().then((buff: ArrayBuffer) => {
- postAudioChunk(buff);
- });
- });
-
- // get audio and post new message to backend
- mediaRecorder.addEventListener('stop', (_e: Event) => {
- invokeReturnAudio().then((audio: ArrayBuffer[] | Error) => {
- console.log(audio);
- // postMessage(newMessage({audio: audio}));
- });
- });
-
- });
-
- // start recording on space bar
- const record = () => {
- console.log("INPT:Capturing audio...")
- mediaRecorder.start();
- recording.value = true;
- show()
- }
-
- // stop recording and send on release
- const stop = () => {
- console.log("INPT:Stopping record.")
- mediaRecorder.stop();
- recording.value = false;
- hide();
- }
-
- const onKeyDown = (e: KeyboardEvent) => {
- if (e.keyCode == 32 && !typing.value) record();
- }
-
- const onKeyUp = (e: KeyboardEvent) => {
- if (e.keyCode == 32 && recording.value) stop();
- }
-
- //-----------------------------------------------------------
-
- onMounted(() => {
- window.addEventListener("keydown", onKeyDown);
- window.addEventListener("keyup", onKeyUp);
- });
-
- onUnmounted(() => {
- window.removeEventListener("keydown", onKeyDown);
- window.removeEventListener("keyup", onKeyUp);
- })
-
- return {
- recording
- }
-
-}
diff --git a/src/render/components/controllers/inputItem.control.text.ts b/src/render/components/controllers/inputItem.control.text.ts
deleted file mode 100644
index 941ae89..0000000
--- a/src/render/components/controllers/inputItem.control.text.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import { Ref, ref, watch, onMounted, onUnmounted } from "vue";
-import { postMessage } from "@/render/ipc";
-import { newMessage, animateTextInput } from "./helpers";
-
-
-export default function useTextInputController(elementX: Ref) {
-
- let textInput: HTMLInputElement | null;
-
- const { side, show, hide, switchSide } = animateTextInput();
-
- let firstKey = true;
- const typing = ref(false);
-
- // Prep inputItem for typing.
- const prepInput = () => {
- show()
- typing.value = true
- }
-
- // Clear and hide inputItem after done typing.
- const clearInput = () => {
-
- if (textInput) {
- textInput.value = "";
- textInput.blur();
- }
-
- hide()
- firstKey = true;
- typing.value = false;
- }
-
- // Send a message and clean up after.
- const sendMessage = () => {
- if (textInput) {
-
- // Send it to the backend for processing.
- const message = newMessage({
- text: false
- });
-
- // postMessage(message);
-
- clearInput()
- }
- }
-
- // Keys that are capable of opening the text input (numbers and letters).
- const isHotKey = (key: number) => {
- if (key >= 47 && key <= 91) { // a letter
- return true
- }
- }
-
- //---Callbacks-----------------------------------------------
-
- const onKeyDown = (e: KeyboardEvent) => {
- const key = e.keyCode;
-
- if (textInput) {
-
- // Only runs on firstKey.
- if (firstKey) {
-
- if (!isHotKey(key)) {
- return
- }
-
- prepInput()
- }
-
- textInput.focus();
-
- // Close input when no text or on ESC.
- if ((textInput.value == "") && (!firstKey) && (key === 8)) { // backspace
- clearInput()
- return
- }
-
- if (key === 27) { // escape
- clearInput()
- return
- }
-
- // Close and send on enter.
- if (key === 13) {
- if (textInput.value) {
- sendMessage()
- return
- }
- }
-
- if (firstKey) firstKey = false
- }
- }
-
- //-----------------------------------------------------------
-
- // Watch parent position and update side.
- watch(elementX, (elementX, _previous) => {
- const winW = window.innerWidth
-
- // Logic depends on the side we are on.
- if (side.value === "right") {
- if (winW - elementX < 230) {
- switchSide()
- side.value = "left"
- }
- }
-
- else {
- if (winW - elementX > 230) {
- switchSide()
- side.value = "right"
- }
- }
-
- });
-
- onMounted(() => {
- textInput = document.getElementById("textInput") as HTMLInputElement;
- window.addEventListener("keydown", onKeyDown);
- })
-
- onUnmounted(() => {
- window.removeEventListener("keydown", onKeyDown);
- });
-
- return {
- typing
- }
-
-}
diff --git a/src/render/components/controllers/messenger.control.ts b/src/render/components/controllers/messenger.control.ts
deleted file mode 100644
index b9c3a96..0000000
--- a/src/render/components/controllers/messenger.control.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { ref } from 'vue';
-import useScroll from "@/render/composables/useScroll";
-
-const messagesRef = ref();
-
-/* seed the canvas with messages */
-const seedCanvas = (messages: Message[]) => {
- messagesRef.value = messages;
-}
-
-const addMessage = (message: Message) => {
- messagesRef.value.push(message);
-}
-
-const updateMessage = (message: Message) => {
-
- let target_message = messagesRef.value.filter((m: Message) => {
- return m.uid = message.uid;
- })[0];
-
- if (target_message) {
- target_message = message;
- }
-
-}
-
-export default function useMessages() {
-
- const { updateScrollRef, adjustScroll } = useScroll("messenger");
-
- return {
- messagesRef,
- seedCanvas,
- addMessage,
- updateMessage
- };
-
-}
diff --git a/src/render/components/header.js b/src/render/components/header.js
new file mode 100644
index 0000000..0851a69
--- /dev/null
+++ b/src/render/components/header.js
@@ -0,0 +1,23 @@
+const Header =
+{
+ setup() {
+ const onNavBar = (command) => window.mainApi.send('nav-bar', command);
+ return { onNavBar };
+ },
+
+ template: `
+
+
+ `
+}
+
+export default Header;
\ No newline at end of file
diff --git a/src/render/components/header.vue b/src/render/components/header.vue
deleted file mode 100644
index 63716c8..0000000
--- a/src/render/components/header.vue
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/render/components/input.js b/src/render/components/input.js
new file mode 100644
index 0000000..5bc8144
--- /dev/null
+++ b/src/render/components/input.js
@@ -0,0 +1,55 @@
+import useText from "./control/text.js";
+import draggify from "./control/draggify.js";
+
+const Input =
+{
+ props: ["person"],
+
+ setup(props)
+ {
+ const initials = Vue.ref("");
+
+ const recording = Vue.ref(false);
+
+ const { elementX, elementY } = draggify("input", 15);
+
+ const { leftSide, show } = useText("input-text", elementX);
+
+ window.mainApi.on("record", (status) => recording.value = status);
+
+ Vue.watch(() => props.person, (c, _p) => initials.value = getInitials(c));
+
+ return { initials, elementX, elementY, recording, leftSide, show };
+ },
+
+ template: `
+ `
+}
+
+function getInitials(name)
+{
+ let rgx = new RegExp(/(\p{L}{1})\p{L}+/, 'gu');
+
+ let initials = [...name.matchAll(rgx)] || [];
+
+ return (
+ (initials.shift()?.[1] || '') + (initials.pop()?.[1] || '')
+ ).toUpperCase();
+}
+
+export default Input;
diff --git a/src/render/components/inputItem.vue b/src/render/components/inputItem.vue
deleted file mode 100644
index edd844f..0000000
--- a/src/render/components/inputItem.vue
+++ /dev/null
@@ -1,220 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/render/components/login.js b/src/render/components/login.js
new file mode 100644
index 0000000..da2e080
--- /dev/null
+++ b/src/render/components/login.js
@@ -0,0 +1,58 @@
+const Login =
+{
+ setup()
+ {
+ const usr = Vue.ref("");
+ const pwd = Vue.ref("");
+
+ const submitForm = async () => {
+ const success = await window.mainApi.invoke("login", usr.value, pwd.value);
+ if (!success) shake("login-form");
+ }
+
+ return { usr, pwd, submitForm };
+ },
+
+ template: `
+ `
+}
+
+/** Shake a div to indicate incorrect credentials */
+const shake = (elementId) =>
+{
+ const el = document.getElementById(elementId);
+
+ if (el)
+ el.classList.remove("shake");
+
+ setTimeout(() => {
+ if (el) el.classList.add("shake");
+ }, 250);
+}
+
+export default Login;
\ No newline at end of file
diff --git a/src/render/components/login.vue b/src/render/components/login.vue
deleted file mode 100644
index bece6ea..0000000
--- a/src/render/components/login.vue
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/render/components/message.js b/src/render/components/message.js
new file mode 100644
index 0000000..fd1b41c
--- /dev/null
+++ b/src/render/components/message.js
@@ -0,0 +1,60 @@
+import Bubble from "./bubble.js";
+import Context from "./context.js";
+
+const Message =
+{
+ components: {
+ Bubble,
+ Context
+ },
+
+ props: ["modifier", "content", "context", "avatar", "id"],
+
+ setup(props)
+ {
+ return { calcChild };
+ },
+
+ template: `
+
+
+
+
+
+
+
`
+}
+
+function calcChild(index, len)
+{
+ if (len === 1)
+ {
+ return "none-child";
+ }
+ else if (index === 0)
+ {
+ return "first-child";
+ }
+ else if (index === len - 1)
+ {
+ return "last-child";
+ }
+ else
+ {
+ return "middle-child";
+ }
+}
+
+export default Message;
diff --git a/src/render/components/messenger.js b/src/render/components/messenger.js
new file mode 100644
index 0000000..668b505
--- /dev/null
+++ b/src/render/components/messenger.js
@@ -0,0 +1,102 @@
+import initScroll from "./control/scroll.js";
+
+import WS from "./ws.js";
+import Input from "./input.js";
+import Settings from "./settings.js";
+import Message from "./message.js";
+
+const Messenger = {
+
+ components: {
+ WS,
+ Settings,
+ Message,
+ Input
+ },
+
+ setup()
+ {
+ const person = Vue.ref("");
+ const messages = Vue.ref([{
+ modifier: "ai",
+ content: [{
+ category: "text/html",
+ text: `
+
About HTML Parser
+
Return the text of the most recently opened start tag. This should not normally be needed for structured processing, but may be useful in dealing with HTML “as deployed” or for re-generating input with minimal changes (whitespace between attributes can be preserved, etc.).
+
`,
+ blob: null
+ }],
+ context: "Email from David Spade",
+ avatar: null,
+ id: 0
+ }]);
+
+ const onDrop = async (e) => {
+ const file = e.dataTransfer.items[0].getAsFile();
+
+ const buffer = await file.arrayBuffer();
+ const b64String = await window.mainApi.invoke("encode", buffer);
+
+ window.mainApi.send("message", {
+ category: file.type,
+ text: file.name,
+ blob: b64String
+ });
+ }
+
+ Vue.onMounted(() => {
+
+ window.mainApi.on("message", (message) => {
+ if (message.person)
+ {
+ person.value = message.person;
+ messages.value = message.messages;
+ }
+ else if (message.name)
+ {
+ person.value = message;
+ }
+ else if (message.content)
+ {
+ messages.value.push(message);
+ }
+ else
+ {
+ messages.value[messages.value.length - 1].content.push(message);
+ }
+ });
+
+ initScroll("messenger");
+ window.mainApi.send("messenger");
+ });
+
+ Vue.onUnmounted(() => {
+ messages.value = [];
+ });
+
+ return { person, messages, onDrop };
+ },
+
+ template: `
+
+
+
+
+
+
+
`
+}
+
+export default Messenger;
diff --git a/src/render/components/messenger.vue b/src/render/components/messenger.vue
deleted file mode 100644
index ee56549..0000000
--- a/src/render/components/messenger.vue
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/render/components/settings.js b/src/render/components/settings.js
new file mode 100644
index 0000000..68d69f2
--- /dev/null
+++ b/src/render/components/settings.js
@@ -0,0 +1,28 @@
+
+const Settings =
+{
+ setup() {
+ const active = Vue.ref(false);
+
+ window.addEventListener("keydown", (e) => {
+ console.log("toggle settings");
+ })
+
+ const logout = async () => {
+ await window.mainApi.send("logout");
+ }
+
+ return { active, logout };
+ },
+
+ template: `
+
+
+
+ Logout
+
+
+
`
+}
+
+export default Settings;
\ No newline at end of file
diff --git a/src/render/components/settings.vue b/src/render/components/settings.vue
deleted file mode 100644
index cf881c3..0000000
--- a/src/render/components/settings.vue
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Logout
-
-
-
-
-
-
-
-
diff --git a/src/render/components/splash.js b/src/render/components/splash.js
new file mode 100644
index 0000000..220eaad
--- /dev/null
+++ b/src/render/components/splash.js
@@ -0,0 +1,50 @@
+const Splash =
+{
+ template: `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+}
+
+export default Splash;
\ No newline at end of file
diff --git a/src/render/components/splash.vue b/src/render/components/splash.vue
deleted file mode 100644
index 247847a..0000000
--- a/src/render/components/splash.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/render/components/ws.js b/src/render/components/ws.js
new file mode 100644
index 0000000..189b03d
--- /dev/null
+++ b/src/render/components/ws.js
@@ -0,0 +1,35 @@
+
+const WS =
+{
+ setup()
+ {
+ const status = Vue.ref();
+
+ Vue.onMounted(() => {
+
+ window.mainApi.on("ws-status", (val) => {
+ status.value = val;
+ });
+
+ });
+
+ return { status }
+ },
+
+ template: `
+
+
+
+
+
+
+
`
+}
+
+export default WS;
\ No newline at end of file
diff --git a/src/render/composables/useDraggify.ts b/src/render/composables/useDraggify.ts
deleted file mode 100644
index f3d8978..0000000
--- a/src/render/composables/useDraggify.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import { onMounted, ref, onUnmounted } from "vue";
-
-//---Dragabble Helper Funcs--------------------------------------
-
-// Calculate distance to nearest side.
-function calcSideProximity (elementX: number, winW: number) {
-
- // Calc right short.
- let short = winW - elementX - 40;
-
- // See if it's left short.
- if (elementX + 20 < winW / 2) {
- short = elementX
- }
-
- return short
-}
-
-// Update elementX or elementY value on window resize
-function calcPosition (elementPosition: number, percent: number,
- short: number, win: number) {
-
- // Is it close to the right/bottom side?
- if (percent > 0.75) {
- elementPosition = win - short - 40;
- }
-
- // Is it not close to a side?
- if (percent < 0.75 && percent > 0.25) {
- elementPosition = win * percent
- }
-
- return elementPosition
-}
-
-export default function draggify(elementId: string, xStart: number,
- yStart: number, margin: number) {
-
- let element: HTMLElement | null;
-
- // Cords of inputItem.
- const elementX = ref(0);
- const elementY = ref(0);
-
- // Position of inputItem on terms of percentage of window.
- let percentX: number;
- let percentY: number;
-
- // How close inputItem is to closest X or Y side.
- let xShort: number;
- let yShort: number;
-
- // Keep track of window size;
- let winW = window.innerWidth;
- let winH = window.innerHeight;
-
- //---Reposition Anime-----------------------------------------------
-
- // Move element to target smoothly.
- const repositionAnime = (xChange: number, yChange: number) => {
- const xStep = xChange / 6000;
- const yStep = yChange / 6000;
-
- for (let i = 1; i <= 6000; i++) {
-
- setTimeout(() => {
- elementX.value += xStep;
- elementY.value += yStep;
- }, 16) // 60fps
-
- }
- }
-
- //---Event Handlers-----------------------------------------------
-
- // Update the position of inputItem on mouse dragging.
- const onMouseMove = (e: any) => {
- e.preventDefault()
- element = document.getElementById(elementId);
-
- if (element) {
- const inputItemRect = element.getBoundingClientRect();
- elementX.value = inputItemRect.left + e.movementX;
- elementY.value = inputItemRect.top + e.movementY;
- }
-
- }
-
- // Add an event listener for dragging.
- const onMouseDown = (_e: any) => {
- _e.preventDefault()
- window.addEventListener('mousemove', onMouseMove, true);
- }
-
- // Update position references when user is done moving targetEl.
- const onMouseUp = (_e: any) => {
- window.removeEventListener('mousemove', onMouseMove, true);
-
- // See if and calculate reposition.
- let x = 0; // vector change
- let y = 0;
-
- if (elementX.value < 0) {
- x = (elementX.value - margin)*-1
- }
-
- if (elementX.value > winW - 40) {
- const b = winW - 40 - margin;
- x = (elementX.value - b)*-1
- }
-
- // Reposition y
- if (elementY.value < 0) {
- y = (elementY.value - margin)*-1
- }
-
- if (elementY.value > winH - 40) {
- const d = winH - 40 - margin;
- y = (elementY.value - d)*-1
- }
-
- // Reposition if needed.
- if (x !== 0 || y !== 0) repositionAnime(x, y);
-
- xShort = calcSideProximity(elementX.value, winW);
- yShort = calcSideProximity(elementY.value, winH);
-
- // Update percentages.
- percentX = elementX.value / winW;
- percentY = elementY.value / winH;
-
- // Save position.
- const position = {
- x: elementX.value,
- y: elementY.value
- }
- window.localStorage.setItem("inputItem_position", JSON.stringify(position));
- }
-
- // Update position of targetEl on windowResize.
- const onWindowResize = (_e: any) => {
-
- // Update window dimensions.
- winW = window.innerWidth;
- winH = window.innerHeight;
-
- elementX.value = calcPosition(elementX.value, percentX, xShort, winW);
- elementY.value = calcPosition(elementY.value, percentY, yShort, winH);
-
- }
-
- //---------------------------------------------------------------
-
- onMounted(() => {
- element = document.getElementById(elementId);
-
- if (element) {
- element.addEventListener('mousedown', onMouseDown, false);
- }
-
- window.addEventListener("mouseup", onMouseUp, false);
-
- // Initialize the positional references.
- percentX = elementX.value / window.innerWidth;
- percentY = elementY.value / window.innerHeight;
-
- xShort = calcSideProximity(elementX.value, window.innerWidth);
- yShort = calcSideProximity(elementX.value, window.innerHeight);
-
- // Then, we can listen for window resize.
- window.addEventListener('resize', onWindowResize, false);
- });
-
- // Try loading initPosition, otherwise set default values
- let initPosition: any;
- const rawData = window.localStorage.getItem("inputItem_position")
-
- if (rawData) {
- initPosition = JSON.parse(rawData)
- } else {
- initPosition = {x: xStart, y: yStart}
- }
-
- elementX.value = initPosition.x;
- elementY.value = initPosition.y;
-
- // remove event listeners on component dismount.
- onUnmounted(() => {
- window.removeEventListener('resize', onWindowResize);
- window.removeEventListener('mouseup', onMouseUp);
- if (element) element.removeEventListener('mousedown', onMouseDown);
- })
-
- return {
- elementX,
- elementY
- }
-
-}
diff --git a/src/render/composables/useIpcRend.ts b/src/render/composables/useIpcRend.ts
deleted file mode 100644
index 9ba7f73..0000000
--- a/src/render/composables/useIpcRend.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-
-import { IpcRendererEvent } from "electron";
-
-export class IpcRendererListener implements IIpcListener {
-
- readonly channel: string;
-
- readonly _listenerCallback: IpcListenerCallback;
-
- constructor(options: {
- channel: string;
- listenerCallback: IpcListenerCallback;
- }) {
- this.channel = options.channel;
- this._listenerCallback = options.listenerCallback;
- }
-
- listen() {
- this.remove();
- window.ipcRenderer.on(this.channel, this._onPost);
- }
-
- remove() {
- window.ipcRenderer.removeAllListeners(this.channel);
- }
-
- private _onPost = (_e: IpcRendererEvent, payload: InputParam): void => {
- console.log(`[IPC] Post: ${this.channel}`);
- this._listenerCallback(payload);
- }
-
-}
-
-
-export default function useIpcRenderer () {
-
- const invoke = async (endpoint: string, payload: any) => {
- try {
- const res = await window.ipcRenderer.invoke(endpoint, payload);
- return res;
- } catch (e) {
- throw e;
- }
- }
-
- const post = (endpoint: string, payload: any) => {
- window.ipcRenderer.send(endpoint, payload);
- };
-
- return {
- invoke,
- post,
- }
-}
diff --git a/src/render/composables/useMessages.ts b/src/render/composables/useMessages.ts
deleted file mode 100644
index f731584..0000000
--- a/src/render/composables/useMessages.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// shared
-import { ref, Ref } from "vue";
-import useScroll from "@/render/composables/useScroll";
-
-export const messages: Ref> = ref([]);
-
-export const setMessages: IpcListenerCallback> = (payload) => {
- messages.value = payload as Array;
-}
-
-export const addMessage: IpcListenerCallback = (payload) => {
- messages.value.push(payload as Message);
-}
-
-export const updateMessage: IpcListenerCallback = (payload) => {
- const message = payload as Message;
-
- let targetMessage = messages.value.filter((m: Message) => {
- return m.uid = message.uid;
- })[0];
-
- if (targetMessage) {
- targetMessage = message;
- }
-
-}
-
-export default {
- messages,
- setMessages,
- addMessage,
- updateMessage
-};
diff --git a/src/render/composables/useProfile.ts b/src/render/composables/useProfile.ts
deleted file mode 100644
index 3575de7..0000000
--- a/src/render/composables/useProfile.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-// shared
-import { ref } from "vue";
-
-export const profile = ref();
-
-export const authComplete = ref(false);
-
-export const setProfile: IpcListenerCallback = (payload) => {
- payload ? profile.value = payload : clearProfile();
- showRender();
-};
-
-export const clearProfile = () => {
- profile.value = null;
-};
-
-export const showRender = () => {
- authComplete.value = true;
-};
-
-export default {
- setProfile,
- clearProfile,
- profile,
- showRender,
- authComplete,
-};
diff --git a/src/render/composables/useScroll.ts b/src/render/composables/useScroll.ts
deleted file mode 100644
index 811e7fc..0000000
--- a/src/render/composables/useScroll.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-export default function useScroll(element: string) {
-
- let isScrolledToBottom: boolean;
- const view = document.getElementById(element)
-
- // Update isScrolledToBottom
- const updateScrollRef = () => {
- if (view) isScrolledToBottom = view.scrollHeight - view.clientHeight <= view.scrollTop + 1;
- return isScrolledToBottom;
- }
-
- // Adjust scroll after we add content to the messenger.
- const adjustScroll = () => {
- if (view) {
- view.scrollTo({
- top: view.scrollHeight - view.clientHeight,
- behavior: 'smooth'
- });
- }
- }
-
- return {
- updateScrollRef,
- adjustScroll,
- };
-
-}
\ No newline at end of file
diff --git a/src/render/index.html b/src/render/index.html
new file mode 100644
index 0000000..e45bb6c
--- /dev/null
+++ b/src/render/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/render/index.js b/src/render/index.js
new file mode 100644
index 0000000..9757f5a
--- /dev/null
+++ b/src/render/index.js
@@ -0,0 +1,2 @@
+import App from "./components/app.js";
+Vue.createApp(App).mount("#app");
diff --git a/src/render/ipc.ts b/src/render/ipc.ts
deleted file mode 100644
index bc68049..0000000
--- a/src/render/ipc.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-
-import useIpc from "@/render/composables/useIpcRend";
-import * as rendererListeners from "./listeners";
-
-const { post, invoke } = useIpc();
-
-/**
- *
- * Account and auth related endpoints
- *
- */
-
-
-export const invokeLogin = async (
- payload: LoginPayload
-): Promise => (
- await invoke('invoke-account-login', JSON.stringify(payload))
-);
-
-export const invokeLogout = async (): Promise => (
- await invoke("invoke-account-logout", null)
-);
-
-/**
- *
- * Audio endpoints
- *
- */
-
-export const postAudioChunk = (chunk: ArrayBuffer): void => (
- post("post-audio-collect", chunk)
-);
-
-export const invokeReturnAudio = async (): Promise => (
- await invoke("invoke-audio-flush", null)
-);
-
-/**
- *
- * Crimata Platform (session) endpoints
- *
- */
-
-export const invokeSession = async (cid: string): Promise => (
- await invoke("messenger-init", cid)
-);
-
-export const postMessage = (payload: Message): void => (
- post('post-session-send', payload)
-);
-
-export const postAppMount = (): void => (
- post('post-app-mount', null)
-);
-
-
-/**
- *
- * Ipc Renderer Listeners
- *
- */
-
-let ipcListeners: IPCListeners = {};
-
-export const initIpcRendererListeners = () => {
- for (const [key, listener] of Object.entries(rendererListeners)) {
- if (!(key in ipcListeners)) {
- ipcListeners[key] = listener;
- listener.listen();
- }
- }
-};
-
-export const removeListeners = () => {
- for (const [key, listener] of Object.entries(rendererListeners)) {
- listener.remove();
- }
- ipcListeners = {};
-};
-
diff --git a/src/render/listeners.ts b/src/render/listeners.ts
deleted file mode 100644
index 876d206..0000000
--- a/src/render/listeners.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-
-import { IpcRendererListener } from "./composables/useIpcRend"
-import { setProfile } from "./composables/useProfile";
-import { setMessages, addMessage, updateMessage } from "./composables/useMessages";
-
-const SET_PROFILE_CHANNEL = "set-profile";
-
-const INIT_MESSAGES_CHANNEL = "init-messages";
-const ADD_MESSAGE_CHANNEL = "add-message";
-const UPDATE_MESSAGE_CHANNEL = "update-message";
-
-export const setProfileListener = new IpcRendererListener({
- channel: SET_PROFILE_CHANNEL,
- listenerCallback: setProfile
-});
-
-export const initMessagesListener = new IpcRendererListener({
- channel: INIT_MESSAGES_CHANNEL,
- listenerCallback: setMessages
-});
-
-
-export const addMessagesListener = new IpcRendererListener({
- channel: ADD_MESSAGE_CHANNEL,
- listenerCallback: addMessage
-});
-
-export const updateMessagesListener = new IpcRendererListener({
- channel: UPDATE_MESSAGE_CHANNEL,
- listenerCallback: updateMessage
-});
-
diff --git a/src/render/main.css b/src/render/main.css
new file mode 100644
index 0000000..f25adda
--- /dev/null
+++ b/src/render/main.css
@@ -0,0 +1,571 @@
+html, body {
+ margin: 0;
+ padding: 0;
+}
+
+/* The first word of the class is the component that it modifys. */
+
+#splash {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+#app {
+ font-family: "SF Pro Text";
+ -webkit-font-smoothing: antialiased;
+ height: 100vh;
+ width: 100vw;
+ border-radius: 15px;
+}
+
+#header-titlebar {
+ position: fixed;
+ width: 100vw;
+ height: 54px;
+ opacity: 0.75;
+ background-color: #EBEBEB;
+ -webkit-app-region: drag;
+ border: none;
+ outline: none;
+ z-index: 1;
+}
+
+.contacts {
+ margin: 0;
+ padding: 0;
+ border-radius: inherit;
+ background-color: #DBDBDB;
+}
+
+.contacts > li {
+ padding: 12px;
+ display: flex;
+}
+
+.contacts img {
+ border-radius: 50%;
+}
+
+.contacts .info {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.contacts .name {
+
+}
+
+.contacts .email {
+ font-family: SF Compact Display;
+ font-weight: bold;
+ font-size: 12px;
+ color: #898989;
+}
+
+.mail {
+ padding: 12px;
+ margin: 0px;
+ background-color: #D6F2FF;
+ border-radius: inherit;
+}
+
+.mail h4 {
+ margin-top: 0px;
+}
+
+.mail p {
+ margin-bottom: 0px;
+}
+
+#header-menu {
+ position: fixed;
+ margin-left: 20px;
+ margin-top: 20px;
+ z-index: 2;
+}
+
+.header-menu-button {
+ min-width: 14px;
+ min-height: 14px;
+ border-radius: 7px;
+}
+
+.header-exit-button {
+ background-color: #FF6157;
+}
+
+.header-exit-button:active {
+ background: #c14645;
+}
+
+.header-min-button {
+ background-color: #FFC12F;
+ margin-left: 8px;
+}
+
+.header-min-button:active {
+ background-color: #c08e38;
+}
+
+#login {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+#login-form {
+ font-family: "SF Compact Display";
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding-bottom: 20px;
+}
+
+.login-input-box {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 10px;
+}
+
+.login-input {
+ background-color: #B9B9B9;
+ border: none;
+ outline: none;
+ padding: 16px;
+ text-decoration: none;
+ margin: 4px 2px;
+ cursor: pointer;
+ border-radius: 10px;
+}
+
+.login-input-modifier {
+ min-width: 181px;
+ font-size: 12px;
+ font-weight: bold;
+ text-align: left;
+ margin-left: 15px;
+}
+
+.login-submit-button {
+ font-family: "SF Compact Display";
+ position: fixed;
+ margin-top: 260px;
+ background-color: #58C4FD;
+ color: white;
+ padding: 10px 30px;
+ border-radius: 20px;
+ font-size: 14px;
+ font-weight: bold;
+}
+
+.login-submit-button:active {
+ background-color: #4296C3;
+}
+
+/* generic shaking functionality */
+.shake {
+ animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
+ transform: translate3d(0, 0, 0);
+ backface-visibility: hidden;
+ perspective: 1000px;
+}
+
+@keyframes shake {
+ 10%, 90% {
+ transform: translate3d(-1px, 0, 0);
+ }
+
+ 20%, 80% {
+ transform: translate3d(2px, 0, 0);
+ }
+
+ 30%, 50%, 70% {
+ transform: translate3d(-4px, 0, 0);
+ }
+
+ 40%, 60% {
+ transform: translate3d(4px, 0, 0);
+ }
+}
+
+#messenger {
+ width: 100vw;
+ height: 100vh;
+ overflow: auto;
+}
+
+/* hide native scrollbar */
+#messenger::-webkit-scrollbar {
+ display: none;
+}
+
+#ws {
+ position: fixed;
+ width: 100vw;
+ height: 54px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1;
+}
+
+#ws-logo {
+ transition: all 0.5s;
+}
+
+#ws-logo.move {
+ transform: translateX(15px);
+}
+
+#ws-dots {
+ opacity: 0;
+ transition: all 0.5s;
+}
+
+#ws-dots.move {
+ opacity: 1;
+ transform: translateX(-15px);
+}
+
+.ws-dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background-color: #48E065;
+ position: relative;
+ transform: translateX(-15px);
+ animation: ws-dot-flashing 1s infinite linear alternate;
+ animation-delay: .25s;
+}
+
+.ws-dot::before, .ws-dot::after {
+ content: '';
+ display: inline-block;
+ position: absolute;
+}
+
+.ws-dot::before {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background-color: #48E065;
+ left: -9px;
+ animation: ws-dot-flashing 1s infinite alternate;
+ animation-delay: 0s;
+}
+
+.ws-dot::after {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background-color: #48E065;
+ left: 9px;
+ animation: ws-dot-flashing 1s infinite alternate;
+ animation-delay: 0.5s;
+}
+
+@keyframes ws-dot-flashing {
+ 0% {
+ background-color: #48E065;
+ }
+ 50%,
+ 100% {
+ background-color: #9B9B9B;
+ }
+}
+
+#input {
+ position: absolute;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ width: 40px;
+ height: 40px;
+ z-index: 3;
+ /* To prevent window drag when overlapping with titlebar. */
+ -webkit-app-region: no-drag;
+ border-radius: 50%;
+ /* Set opacity here to not affect child. */
+ background-color: rgba(235, 235, 235, 0.75);
+ cursor: pointer;
+ box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15);
+}
+
+#input-text {
+ position: absolute;
+ min-width: 150px;
+ height: 16px;
+ border-radius: 18px;
+ padding: 10px;
+ outline: none;
+ border: none;
+ pointer-events: none;
+ background-color: white;
+ z-index: -1;
+ box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15);
+ transform-origin: center;
+ opacity: 0;
+ transform: translateX(70%);
+ transition: all 0.5s;
+}
+
+#input-text.show {
+ opacity: 1;
+}
+
+#input-text.leftSide {
+ transform: translateX(-70%);
+}
+
+#settings {
+ position: fixed;
+ width: 100vw;
+ height: 100vh;
+ background-color: rgba(235, 235, 235, 0.75);
+ z-index: 4;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ animation-name: settings-appear;
+ animation-duration: 0.5s;
+}
+
+@keyframes settings-appear {
+ from {
+ background-color: rgba(235, 235, 235, 0);
+ }
+ to {
+ background-color: rgba(235, 235, 235, 0.75);
+ }
+}
+
+.settings-icon {
+ position: fixed;
+ right: 0;
+ border: none;
+ outline: none;
+ display: flex;
+ flex-direction: row;
+ padding: 5px;
+ margin-right: 20px;
+ margin-top: 19px;
+ z-index: 2;
+ background-color: Transparent;
+}
+
+.settings-icon:hover {
+ cursor: pointer;
+}
+
+.settings-account {
+ font-size: 12px;
+ font-weight: bold;
+ margin-bottom: 25px;
+}
+
+.settings-logout-button {
+ font-family: "SF Compact Display";
+ background-color: #B7B7B7;
+ padding: 10px 30px;
+ border-radius: 20px;
+ font-size: 14px;
+ font-weight: bold;
+}
+
+.settings-logout-button:hover {
+ cursor: pointer;
+}
+
+.settings-version {
+ position: absolute;
+ left: 50%;
+ top: 75%;
+ transform: translate(-50%, -50%);
+ font-size: 12px;
+ font-weight: bold;
+ color: #575757;
+}
+
+.message {
+ width: 100vw;
+ display: flex;
+ flex-direction: column;
+ padding-top: 9px;
+ padding-bottom: 9px;
+ animation-name: message-init-anim;
+ animation-duration: 0.25s;
+}
+
+@keyframes message-init-anim {
+ from {
+ opacity: 0;
+ } to {
+ opacity: 1;
+ }
+}
+
+.message:first-child {
+ margin-top: 55px;
+}
+
+.message:last-child {
+ margin-bottom: 6px;
+}
+
+.client-message {
+ align-items: flex-end;
+}
+
+.ai-message {
+ align-items: flex-start;
+}
+
+.bubble {
+ position: relative;
+ max-width: 66vw;
+ font-family: "SF Pro Text";
+ font-size: 14px;
+ border-radius: 18px;
+ margin-bottom: 4px;
+}
+
+.ai-bubble {
+ background-color: #FFFFFF;
+ margin-left: 15px;
+}
+
+.client-bubble {
+ color: white;
+ background-color: #58C4FD;
+ margin-right: 15px;
+}
+
+.ai-first-child {
+ border-bottom-left-radius: 9px;
+}
+
+.ai-middle-child {
+ border-top-left-radius: 9px;
+ border-bottom-left-radius: 9px;
+}
+
+.ai-last-child {
+ border-top-left-radius: 9px;
+}
+
+.client-first-child {
+ border-bottom-right-radius: 9px;
+}
+
+.client-middle-child {
+ border-top-right-radius: 9px;
+ border-bottom-right-radius: 9px;
+}
+
+.client-last-child {
+ border-top-right-radius: 9px;
+}
+
+.bubble > p {
+ margin: 0px;
+ padding: 10px;
+}
+
+.bubble > div {
+ border-radius: inherit;
+}
+
+.bubble > img {
+ border-radius: inherit;
+ display: block;
+ max-width: inherit;
+}
+
+.bubble a {
+ border-radius: inherit;
+ font-family: "SF Compact Rounded";
+ background-color: #D9D9D9;
+ font-weight: bold;
+ padding: 12px;
+ color: #727272;
+ margin: 0px;
+}
+
+.context {
+ position: relative;
+ min-height: 14px;
+ display: flex;
+ align-items: center;
+ font-family: "SF Compact Display";
+ font-size: 12px;
+ font-weight: bold;
+ margin-top: 5px;
+}
+
+.ai-context {
+ margin-left: 15px;
+}
+
+.client-context {
+ margin-right: 15px;
+}
+
+.context-avatar {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 30px;
+ height: 30px;
+ background-color: white;
+ border-radius: 15px;
+ margin-right: 5px;
+}
+
+.context-avatar img {
+ border-radius: 50%;
+}
+
+/* ---------- shared between components ---------- */
+
+.button {
+ border: none;
+ outline: none;
+ text-decoration: none;
+}
+
+/*.button:hover {
+ cursor: pointer;
+}*/
+
+.audio {
+ animation-name: audio-anim;
+ animation-duration: 2s;
+ animation-iteration-count: infinite;
+}
+
+@keyframes audio-anim {
+ 0%,
+ 100% {
+ box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.4), 0 0 0 0.25em rgba(195, 195, 195, 0.15);
+ }
+ 25% {
+ box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.15), 0 0 0 0.4em rgba(195, 195, 195, 0.3);
+ }
+ 50% {
+ box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.55), 0 0 0 0.15em rgba(195, 195, 195, 0.05);
+ }
+ 75% {
+ box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25), 0 0 0 0.55em rgba(195, 195, 195, 0.45);
+ }
+}
diff --git a/src/render/main.ts b/src/render/main.ts
deleted file mode 100644
index 5375889..0000000
--- a/src/render/main.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-
-// src/main.ts
-
-import App from "./App.vue";
-
-import mitt from "mitt";
-import { createApp } from "vue";
-
-import { initIpcRendererListeners } from "./ipc"
-
-
-// Handle ipcMain events.
-initIpcRendererListeners();
-
-// Handle events.
-const emitter = mitt();
-
-const app = createApp(App);
-
-app.provide("mitt", emitter);
-app.mount("#app");
diff --git a/src/render/preload.js b/src/render/preload.js
new file mode 100644
index 0000000..9b50adf
--- /dev/null
+++ b/src/render/preload.js
@@ -0,0 +1,53 @@
+const { contextBridge, ipcRenderer } = require("electron");
+
+/** The main <-> render interface */
+
+const validFromMainChannels = [
+ "set-account",
+ "message",
+ "ws-status",
+ "record",
+ "playback"
+];
+
+const validToMain = [
+ "messenger",
+ "message",
+ "login",
+ "logout",
+ "encode",
+ "decode"
+]
+
+ipcRenderer.setMaxListeners(250);
+
+// Expose protected methods that allow the renderer process to use
+// the ipcRenderer without exposing the entire object
+// TODO: Implement argument filtering for added security
+contextBridge.exposeInMainWorld(
+ "mainApi", {
+ invoke: async (channel, ...args) => {
+ if (validToMain.includes(channel)) {
+ try {
+ const res = await ipcRenderer.invoke(channel, ...args);
+ return res;
+ } catch (e) {
+ console.log("IPCRenderer.invoke error");
+ }
+ }
+ },
+ send: (channel, ...args) => {
+ if (validToMain.includes(channel)) {
+ ipcRenderer.send(channel, ...args);
+ }
+ },
+ on: (channel, func) => {
+ if (validFromMainChannels.includes(channel)) {
+ ipcRenderer.on(channel, (event, ...args) => func(...args));
+ }
+ },
+ removeAllListeners: (channel) => {
+ ipcRenderer.removeAllListeners(channel);
+ }
+ }
+);
diff --git a/src/render/preload.ts b/src/render/preload.ts
deleted file mode 100644
index 054f672..0000000
--- a/src/render/preload.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-// All of the Node.js APIs are available in the preload process.
-// It has the same sandbox as a Chrome extension.
-import { ipcRenderer } from "electron";
-
-declare global {
- interface Window {
- ipcRenderer: typeof ipcRenderer;
- }
-}
-
-window.ipcRenderer = ipcRenderer;
-
-process.once("loaded", () => {
-
- window.addEventListener("message", event => {
-
- // do something with custom event
- const message = event.data;
-
- if (message.endpoint === "update-menu-bar") {
- ipcRenderer.send("update-menu-bar", message.content);
- }
-
- if (message.endpoint === "update-recorder") {
- ipcRenderer.send("update-recorder", message.content);
- }
-
- if (message.endpoint === "client-message") {
- ipcRenderer.send("client-message", message.content);
- }
-
- if (message.endpoint === "logout") {
- ipcRenderer.send("logout", message.content);
- }
-
- });
-
-});
diff --git a/src/render/shims-vue.d.ts b/src/render/shims-vue.d.ts
deleted file mode 100644
index 35a61a9..0000000
--- a/src/render/shims-vue.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-declare module "*.vue" {
- import { defineComponent } from "vue";
- const component: ReturnType;
- export default component;
-}
-
-declare module "anime-js" {
- namespace anime {
- import * as anime from "animejs/lib/anime.es.js";
- function anime(): void;
- export = anime;
- }
-}
diff --git a/src/render/vendor/vue.js b/src/render/vendor/vue.js
new file mode 100644
index 0000000..6e5ee00
--- /dev/null
+++ b/src/render/vendor/vue.js
@@ -0,0 +1,15872 @@
+var Vue = (function (exports) {
+ 'use strict';
+
+ /**
+ * Make a map and return a function for checking if a key
+ * is in that map.
+ * IMPORTANT: all calls of this function must be prefixed with
+ * \/\*#\_\_PURE\_\_\*\/
+ * So that rollup can tree-shake them if necessary.
+ */
+ function makeMap(str, expectsLowerCase) {
+ const map = Object.create(null);
+ const list = str.split(',');
+ for (let i = 0; i < list.length; i++) {
+ map[list[i]] = true;
+ }
+ return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
+ }
+
+ /**
+ * dev only flag -> name mapping
+ */
+ const PatchFlagNames = {
+ [1 /* TEXT */]: `TEXT`,
+ [2 /* CLASS */]: `CLASS`,
+ [4 /* STYLE */]: `STYLE`,
+ [8 /* PROPS */]: `PROPS`,
+ [16 /* FULL_PROPS */]: `FULL_PROPS`,
+ [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
+ [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
+ [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
+ [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
+ [512 /* NEED_PATCH */]: `NEED_PATCH`,
+ [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
+ [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
+ [-1 /* HOISTED */]: `HOISTED`,
+ [-2 /* BAIL */]: `BAIL`
+ };
+
+ /**
+ * Dev only
+ */
+ const slotFlagsText = {
+ [1 /* STABLE */]: 'STABLE',
+ [2 /* DYNAMIC */]: 'DYNAMIC',
+ [3 /* FORWARDED */]: 'FORWARDED'
+ };
+
+ const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
+ 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
+ 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
+ const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
+
+ const range = 2;
+ function generateCodeFrame(source, start = 0, end = source.length) {
+ // Split the content into individual lines but capture the newline sequence
+ // that separated each line. This is important because the actual sequence is
+ // needed to properly take into account the full line length for offset
+ // comparison
+ let lines = source.split(/(\r?\n)/);
+ // Separate the lines and newline sequences into separate arrays for easier referencing
+ const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
+ lines = lines.filter((_, idx) => idx % 2 === 0);
+ let count = 0;
+ const res = [];
+ for (let i = 0; i < lines.length; i++) {
+ count +=
+ lines[i].length +
+ ((newlineSequences[i] && newlineSequences[i].length) || 0);
+ if (count >= start) {
+ for (let j = i - range; j <= i + range || end > count; j++) {
+ if (j < 0 || j >= lines.length)
+ continue;
+ const line = j + 1;
+ res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
+ const lineLength = lines[j].length;
+ const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
+ if (j === i) {
+ // push underline
+ const pad = start - (count - (lineLength + newLineSeqLength));
+ const length = Math.max(1, end > count ? lineLength - pad : end - start);
+ res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
+ }
+ else if (j > i) {
+ if (end > count) {
+ const length = Math.max(Math.min(end - count, lineLength), 1);
+ res.push(` | ` + '^'.repeat(length));
+ }
+ count += lineLength + newLineSeqLength;
+ }
+ }
+ break;
+ }
+ }
+ return res.join('\n');
+ }
+
+ /**
+ * On the client we only need to offer special cases for boolean attributes that
+ * have different names from their corresponding dom properties:
+ * - itemscope -> N/A
+ * - allowfullscreen -> allowFullscreen
+ * - formnovalidate -> formNoValidate
+ * - ismap -> isMap
+ * - nomodule -> noModule
+ * - novalidate -> noValidate
+ * - readonly -> readOnly
+ */
+ const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
+ const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
+ /**
+ * Boolean attributes should be included if the value is truthy or ''.
+ * e.g. compiles to { multiple: '' }
+ */
+ function includeBooleanAttr(value) {
+ return !!value || value === '';
+ }
+
+ function normalizeStyle(value) {
+ if (isArray(value)) {
+ const res = {};
+ for (let i = 0; i < value.length; i++) {
+ const item = value[i];
+ const normalized = isString(item)
+ ? parseStringStyle(item)
+ : normalizeStyle(item);
+ if (normalized) {
+ for (const key in normalized) {
+ res[key] = normalized[key];
+ }
+ }
+ }
+ return res;
+ }
+ else if (isString(value)) {
+ return value;
+ }
+ else if (isObject(value)) {
+ return value;
+ }
+ }
+ const listDelimiterRE = /;(?![^(]*\))/g;
+ const propertyDelimiterRE = /:(.+)/;
+ function parseStringStyle(cssText) {
+ const ret = {};
+ cssText.split(listDelimiterRE).forEach(item => {
+ if (item) {
+ const tmp = item.split(propertyDelimiterRE);
+ tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
+ }
+ });
+ return ret;
+ }
+ function normalizeClass(value) {
+ let res = '';
+ if (isString(value)) {
+ res = value;
+ }
+ else if (isArray(value)) {
+ for (let i = 0; i < value.length; i++) {
+ const normalized = normalizeClass(value[i]);
+ if (normalized) {
+ res += normalized + ' ';
+ }
+ }
+ }
+ else if (isObject(value)) {
+ for (const name in value) {
+ if (value[name]) {
+ res += name + ' ';
+ }
+ }
+ }
+ return res.trim();
+ }
+ function normalizeProps(props) {
+ if (!props)
+ return null;
+ let { class: klass, style } = props;
+ if (klass && !isString(klass)) {
+ props.class = normalizeClass(klass);
+ }
+ if (style) {
+ props.style = normalizeStyle(style);
+ }
+ return props;
+ }
+
+ // These tag configs are shared between compiler-dom and runtime-dom, so they
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
+ const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
+ 'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
+ 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
+ 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
+ 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
+ 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
+ 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
+ 'option,output,progress,select,textarea,details,dialog,menu,' +
+ 'summary,template,blockquote,iframe,tfoot';
+ // https://developer.mozilla.org/en-US/docs/Web/SVG/Element
+ const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
+ 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
+ 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
+ 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
+ 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
+ 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
+ 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
+ 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
+ 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
+ 'text,textPath,title,tspan,unknown,use,view';
+ const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
+ const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
+ const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
+ const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
+
+ function looseCompareArrays(a, b) {
+ if (a.length !== b.length)
+ return false;
+ let equal = true;
+ for (let i = 0; equal && i < a.length; i++) {
+ equal = looseEqual(a[i], b[i]);
+ }
+ return equal;
+ }
+ function looseEqual(a, b) {
+ if (a === b)
+ return true;
+ let aValidType = isDate(a);
+ let bValidType = isDate(b);
+ if (aValidType || bValidType) {
+ return aValidType && bValidType ? a.getTime() === b.getTime() : false;
+ }
+ aValidType = isArray(a);
+ bValidType = isArray(b);
+ if (aValidType || bValidType) {
+ return aValidType && bValidType ? looseCompareArrays(a, b) : false;
+ }
+ aValidType = isObject(a);
+ bValidType = isObject(b);
+ if (aValidType || bValidType) {
+ /* istanbul ignore if: this if will probably never be called */
+ if (!aValidType || !bValidType) {
+ return false;
+ }
+ const aKeysCount = Object.keys(a).length;
+ const bKeysCount = Object.keys(b).length;
+ if (aKeysCount !== bKeysCount) {
+ return false;
+ }
+ for (const key in a) {
+ const aHasKey = a.hasOwnProperty(key);
+ const bHasKey = b.hasOwnProperty(key);
+ if ((aHasKey && !bHasKey) ||
+ (!aHasKey && bHasKey) ||
+ !looseEqual(a[key], b[key])) {
+ return false;
+ }
+ }
+ }
+ return String(a) === String(b);
+ }
+ function looseIndexOf(arr, val) {
+ return arr.findIndex(item => looseEqual(item, val));
+ }
+
+ /**
+ * For converting {{ interpolation }} values to displayed strings.
+ * @private
+ */
+ const toDisplayString = (val) => {
+ return val == null
+ ? ''
+ : isArray(val) ||
+ (isObject(val) &&
+ (val.toString === objectToString || !isFunction(val.toString)))
+ ? JSON.stringify(val, replacer, 2)
+ : String(val);
+ };
+ const replacer = (_key, val) => {
+ // can't use isRef here since @vue/shared has no deps
+ if (val && val.__v_isRef) {
+ return replacer(_key, val.value);
+ }
+ else if (isMap(val)) {
+ return {
+ [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
+ entries[`${key} =>`] = val;
+ return entries;
+ }, {})
+ };
+ }
+ else if (isSet(val)) {
+ return {
+ [`Set(${val.size})`]: [...val.values()]
+ };
+ }
+ else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
+ return String(val);
+ }
+ return val;
+ };
+
+ const EMPTY_OBJ = Object.freeze({})
+ ;
+ const EMPTY_ARR = Object.freeze([]) ;
+ const NOOP = () => { };
+ /**
+ * Always return false.
+ */
+ const NO = () => false;
+ const onRE = /^on[^a-z]/;
+ const isOn = (key) => onRE.test(key);
+ const isModelListener = (key) => key.startsWith('onUpdate:');
+ const extend = Object.assign;
+ const remove = (arr, el) => {
+ const i = arr.indexOf(el);
+ if (i > -1) {
+ arr.splice(i, 1);
+ }
+ };
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
+ const hasOwn = (val, key) => hasOwnProperty.call(val, key);
+ const isArray = Array.isArray;
+ const isMap = (val) => toTypeString(val) === '[object Map]';
+ const isSet = (val) => toTypeString(val) === '[object Set]';
+ const isDate = (val) => val instanceof Date;
+ const isFunction = (val) => typeof val === 'function';
+ const isString = (val) => typeof val === 'string';
+ const isSymbol = (val) => typeof val === 'symbol';
+ const isObject = (val) => val !== null && typeof val === 'object';
+ const isPromise = (val) => {
+ return isObject(val) && isFunction(val.then) && isFunction(val.catch);
+ };
+ const objectToString = Object.prototype.toString;
+ const toTypeString = (value) => objectToString.call(value);
+ const toRawType = (value) => {
+ // extract "RawType" from strings like "[object RawType]"
+ return toTypeString(value).slice(8, -1);
+ };
+ const isPlainObject = (val) => toTypeString(val) === '[object Object]';
+ const isIntegerKey = (key) => isString(key) &&
+ key !== 'NaN' &&
+ key[0] !== '-' &&
+ '' + parseInt(key, 10) === key;
+ const isReservedProp = /*#__PURE__*/ makeMap(
+ // the leading comma is intentional so empty string "" is also included
+ ',key,ref,' +
+ 'onVnodeBeforeMount,onVnodeMounted,' +
+ 'onVnodeBeforeUpdate,onVnodeUpdated,' +
+ 'onVnodeBeforeUnmount,onVnodeUnmounted');
+ const cacheStringFunction = (fn) => {
+ const cache = Object.create(null);
+ return ((str) => {
+ const hit = cache[str];
+ return hit || (cache[str] = fn(str));
+ });
+ };
+ const camelizeRE = /-(\w)/g;
+ /**
+ * @private
+ */
+ const camelize = cacheStringFunction((str) => {
+ return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
+ });
+ const hyphenateRE = /\B([A-Z])/g;
+ /**
+ * @private
+ */
+ const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
+ /**
+ * @private
+ */
+ const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
+ /**
+ * @private
+ */
+ const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
+ // compare whether a value has changed, accounting for NaN.
+ const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
+ const invokeArrayFns = (fns, arg) => {
+ for (let i = 0; i < fns.length; i++) {
+ fns[i](arg);
+ }
+ };
+ const def = (obj, key, value) => {
+ Object.defineProperty(obj, key, {
+ configurable: true,
+ enumerable: false,
+ value
+ });
+ };
+ const toNumber = (val) => {
+ const n = parseFloat(val);
+ return isNaN(n) ? val : n;
+ };
+ let _globalThis;
+ const getGlobalThis = () => {
+ return (_globalThis ||
+ (_globalThis =
+ typeof globalThis !== 'undefined'
+ ? globalThis
+ : typeof self !== 'undefined'
+ ? self
+ : typeof window !== 'undefined'
+ ? window
+ : typeof global !== 'undefined'
+ ? global
+ : {}));
+ };
+
+ function warn(msg, ...args) {
+ console.warn(`[Vue warn] ${msg}`, ...args);
+ }
+
+ let activeEffectScope;
+ const effectScopeStack = [];
+ class EffectScope {
+ constructor(detached = false) {
+ this.active = true;
+ this.effects = [];
+ this.cleanups = [];
+ if (!detached && activeEffectScope) {
+ this.parent = activeEffectScope;
+ this.index =
+ (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
+ }
+ }
+ run(fn) {
+ if (this.active) {
+ try {
+ this.on();
+ return fn();
+ }
+ finally {
+ this.off();
+ }
+ }
+ else {
+ warn(`cannot run an inactive effect scope.`);
+ }
+ }
+ on() {
+ if (this.active) {
+ effectScopeStack.push(this);
+ activeEffectScope = this;
+ }
+ }
+ off() {
+ if (this.active) {
+ effectScopeStack.pop();
+ activeEffectScope = effectScopeStack[effectScopeStack.length - 1];
+ }
+ }
+ stop(fromParent) {
+ if (this.active) {
+ this.effects.forEach(e => e.stop());
+ this.cleanups.forEach(cleanup => cleanup());
+ if (this.scopes) {
+ this.scopes.forEach(e => e.stop(true));
+ }
+ // nested scope, dereference from parent to avoid memory leaks
+ if (this.parent && !fromParent) {
+ // optimized O(1) removal
+ const last = this.parent.scopes.pop();
+ if (last && last !== this) {
+ this.parent.scopes[this.index] = last;
+ last.index = this.index;
+ }
+ }
+ this.active = false;
+ }
+ }
+ }
+ function effectScope(detached) {
+ return new EffectScope(detached);
+ }
+ function recordEffectScope(effect, scope) {
+ scope = scope || activeEffectScope;
+ if (scope && scope.active) {
+ scope.effects.push(effect);
+ }
+ }
+ function getCurrentScope() {
+ return activeEffectScope;
+ }
+ function onScopeDispose(fn) {
+ if (activeEffectScope) {
+ activeEffectScope.cleanups.push(fn);
+ }
+ else {
+ warn(`onScopeDispose() is called when there is no active effect scope` +
+ ` to be associated with.`);
+ }
+ }
+
+ const createDep = (effects) => {
+ const dep = new Set(effects);
+ dep.w = 0;
+ dep.n = 0;
+ return dep;
+ };
+ const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
+ const newTracked = (dep) => (dep.n & trackOpBit) > 0;
+ const initDepMarkers = ({ deps }) => {
+ if (deps.length) {
+ for (let i = 0; i < deps.length; i++) {
+ deps[i].w |= trackOpBit; // set was tracked
+ }
+ }
+ };
+ const finalizeDepMarkers = (effect) => {
+ const { deps } = effect;
+ if (deps.length) {
+ let ptr = 0;
+ for (let i = 0; i < deps.length; i++) {
+ const dep = deps[i];
+ if (wasTracked(dep) && !newTracked(dep)) {
+ dep.delete(effect);
+ }
+ else {
+ deps[ptr++] = dep;
+ }
+ // clear bits
+ dep.w &= ~trackOpBit;
+ dep.n &= ~trackOpBit;
+ }
+ deps.length = ptr;
+ }
+ };
+
+ const targetMap = new WeakMap();
+ // The number of effects currently being tracked recursively.
+ let effectTrackDepth = 0;
+ let trackOpBit = 1;
+ /**
+ * The bitwise track markers support at most 30 levels op recursion.
+ * This value is chosen to enable modern JS engines to use a SMI on all platforms.
+ * When recursion depth is greater, fall back to using a full cleanup.
+ */
+ const maxMarkerBits = 30;
+ const effectStack = [];
+ let activeEffect;
+ const ITERATE_KEY = Symbol('iterate' );
+ const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
+ class ReactiveEffect {
+ constructor(fn, scheduler = null, scope) {
+ this.fn = fn;
+ this.scheduler = scheduler;
+ this.active = true;
+ this.deps = [];
+ recordEffectScope(this, scope);
+ }
+ run() {
+ if (!this.active) {
+ return this.fn();
+ }
+ if (!effectStack.includes(this)) {
+ try {
+ effectStack.push((activeEffect = this));
+ enableTracking();
+ trackOpBit = 1 << ++effectTrackDepth;
+ if (effectTrackDepth <= maxMarkerBits) {
+ initDepMarkers(this);
+ }
+ else {
+ cleanupEffect(this);
+ }
+ return this.fn();
+ }
+ finally {
+ if (effectTrackDepth <= maxMarkerBits) {
+ finalizeDepMarkers(this);
+ }
+ trackOpBit = 1 << --effectTrackDepth;
+ resetTracking();
+ effectStack.pop();
+ const n = effectStack.length;
+ activeEffect = n > 0 ? effectStack[n - 1] : undefined;
+ }
+ }
+ }
+ stop() {
+ if (this.active) {
+ cleanupEffect(this);
+ if (this.onStop) {
+ this.onStop();
+ }
+ this.active = false;
+ }
+ }
+ }
+ function cleanupEffect(effect) {
+ const { deps } = effect;
+ if (deps.length) {
+ for (let i = 0; i < deps.length; i++) {
+ deps[i].delete(effect);
+ }
+ deps.length = 0;
+ }
+ }
+ function effect(fn, options) {
+ if (fn.effect) {
+ fn = fn.effect.fn;
+ }
+ const _effect = new ReactiveEffect(fn);
+ if (options) {
+ extend(_effect, options);
+ if (options.scope)
+ recordEffectScope(_effect, options.scope);
+ }
+ if (!options || !options.lazy) {
+ _effect.run();
+ }
+ const runner = _effect.run.bind(_effect);
+ runner.effect = _effect;
+ return runner;
+ }
+ function stop(runner) {
+ runner.effect.stop();
+ }
+ let shouldTrack = true;
+ const trackStack = [];
+ function pauseTracking() {
+ trackStack.push(shouldTrack);
+ shouldTrack = false;
+ }
+ function enableTracking() {
+ trackStack.push(shouldTrack);
+ shouldTrack = true;
+ }
+ function resetTracking() {
+ const last = trackStack.pop();
+ shouldTrack = last === undefined ? true : last;
+ }
+ function track(target, type, key) {
+ if (!isTracking()) {
+ return;
+ }
+ let depsMap = targetMap.get(target);
+ if (!depsMap) {
+ targetMap.set(target, (depsMap = new Map()));
+ }
+ let dep = depsMap.get(key);
+ if (!dep) {
+ depsMap.set(key, (dep = createDep()));
+ }
+ const eventInfo = { effect: activeEffect, target, type, key }
+ ;
+ trackEffects(dep, eventInfo);
+ }
+ function isTracking() {
+ return shouldTrack && activeEffect !== undefined;
+ }
+ function trackEffects(dep, debuggerEventExtraInfo) {
+ let shouldTrack = false;
+ if (effectTrackDepth <= maxMarkerBits) {
+ if (!newTracked(dep)) {
+ dep.n |= trackOpBit; // set newly tracked
+ shouldTrack = !wasTracked(dep);
+ }
+ }
+ else {
+ // Full cleanup mode.
+ shouldTrack = !dep.has(activeEffect);
+ }
+ if (shouldTrack) {
+ dep.add(activeEffect);
+ activeEffect.deps.push(dep);
+ if (activeEffect.onTrack) {
+ activeEffect.onTrack(Object.assign({
+ effect: activeEffect
+ }, debuggerEventExtraInfo));
+ }
+ }
+ }
+ function trigger(target, type, key, newValue, oldValue, oldTarget) {
+ const depsMap = targetMap.get(target);
+ if (!depsMap) {
+ // never been tracked
+ return;
+ }
+ let deps = [];
+ if (type === "clear" /* CLEAR */) {
+ // collection being cleared
+ // trigger all effects for target
+ deps = [...depsMap.values()];
+ }
+ else if (key === 'length' && isArray(target)) {
+ depsMap.forEach((dep, key) => {
+ if (key === 'length' || key >= newValue) {
+ deps.push(dep);
+ }
+ });
+ }
+ else {
+ // schedule runs for SET | ADD | DELETE
+ if (key !== void 0) {
+ deps.push(depsMap.get(key));
+ }
+ // also run for iteration key on ADD | DELETE | Map.SET
+ switch (type) {
+ case "add" /* ADD */:
+ if (!isArray(target)) {
+ deps.push(depsMap.get(ITERATE_KEY));
+ if (isMap(target)) {
+ deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
+ }
+ }
+ else if (isIntegerKey(key)) {
+ // new index added to array -> length changes
+ deps.push(depsMap.get('length'));
+ }
+ break;
+ case "delete" /* DELETE */:
+ if (!isArray(target)) {
+ deps.push(depsMap.get(ITERATE_KEY));
+ if (isMap(target)) {
+ deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
+ }
+ }
+ break;
+ case "set" /* SET */:
+ if (isMap(target)) {
+ deps.push(depsMap.get(ITERATE_KEY));
+ }
+ break;
+ }
+ }
+ const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
+ ;
+ if (deps.length === 1) {
+ if (deps[0]) {
+ {
+ triggerEffects(deps[0], eventInfo);
+ }
+ }
+ }
+ else {
+ const effects = [];
+ for (const dep of deps) {
+ if (dep) {
+ effects.push(...dep);
+ }
+ }
+ {
+ triggerEffects(createDep(effects), eventInfo);
+ }
+ }
+ }
+ function triggerEffects(dep, debuggerEventExtraInfo) {
+ // spread into array for stabilization
+ for (const effect of isArray(dep) ? dep : [...dep]) {
+ if (effect !== activeEffect || effect.allowRecurse) {
+ if (effect.onTrigger) {
+ effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
+ }
+ if (effect.scheduler) {
+ effect.scheduler();
+ }
+ else {
+ effect.run();
+ }
+ }
+ }
+ }
+
+ const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
+ const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol)
+ .map(key => Symbol[key])
+ .filter(isSymbol));
+ const get = /*#__PURE__*/ createGetter();
+ const shallowGet = /*#__PURE__*/ createGetter(false, true);
+ const readonlyGet = /*#__PURE__*/ createGetter(true);
+ const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
+ const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
+ function createArrayInstrumentations() {
+ const instrumentations = {};
+ ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
+ instrumentations[key] = function (...args) {
+ const arr = toRaw(this);
+ for (let i = 0, l = this.length; i < l; i++) {
+ track(arr, "get" /* GET */, i + '');
+ }
+ // we run the method using the original args first (which may be reactive)
+ const res = arr[key](...args);
+ if (res === -1 || res === false) {
+ // if that didn't work, run it again using raw values.
+ return arr[key](...args.map(toRaw));
+ }
+ else {
+ return res;
+ }
+ };
+ });
+ ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
+ instrumentations[key] = function (...args) {
+ pauseTracking();
+ const res = toRaw(this)[key].apply(this, args);
+ resetTracking();
+ return res;
+ };
+ });
+ return instrumentations;
+ }
+ function createGetter(isReadonly = false, shallow = false) {
+ return function get(target, key, receiver) {
+ if (key === "__v_isReactive" /* IS_REACTIVE */) {
+ return !isReadonly;
+ }
+ else if (key === "__v_isReadonly" /* IS_READONLY */) {
+ return isReadonly;
+ }
+ else if (key === "__v_raw" /* RAW */ &&
+ receiver ===
+ (isReadonly
+ ? shallow
+ ? shallowReadonlyMap
+ : readonlyMap
+ : shallow
+ ? shallowReactiveMap
+ : reactiveMap).get(target)) {
+ return target;
+ }
+ const targetIsArray = isArray(target);
+ if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
+ return Reflect.get(arrayInstrumentations, key, receiver);
+ }
+ const res = Reflect.get(target, key, receiver);
+ if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
+ return res;
+ }
+ if (!isReadonly) {
+ track(target, "get" /* GET */, key);
+ }
+ if (shallow) {
+ return res;
+ }
+ if (isRef(res)) {
+ // ref unwrapping - does not apply for Array + integer key.
+ const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
+ return shouldUnwrap ? res.value : res;
+ }
+ if (isObject(res)) {
+ // Convert returned value into a proxy as well. we do the isObject check
+ // here to avoid invalid value warning. Also need to lazy access readonly
+ // and reactive here to avoid circular dependency.
+ return isReadonly ? readonly(res) : reactive(res);
+ }
+ return res;
+ };
+ }
+ const set = /*#__PURE__*/ createSetter();
+ const shallowSet = /*#__PURE__*/ createSetter(true);
+ function createSetter(shallow = false) {
+ return function set(target, key, value, receiver) {
+ let oldValue = target[key];
+ if (!shallow) {
+ value = toRaw(value);
+ oldValue = toRaw(oldValue);
+ if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
+ oldValue.value = value;
+ return true;
+ }
+ }
+ const hadKey = isArray(target) && isIntegerKey(key)
+ ? Number(key) < target.length
+ : hasOwn(target, key);
+ const result = Reflect.set(target, key, value, receiver);
+ // don't trigger if target is something up in the prototype chain of original
+ if (target === toRaw(receiver)) {
+ if (!hadKey) {
+ trigger(target, "add" /* ADD */, key, value);
+ }
+ else if (hasChanged(value, oldValue)) {
+ trigger(target, "set" /* SET */, key, value, oldValue);
+ }
+ }
+ return result;
+ };
+ }
+ function deleteProperty(target, key) {
+ const hadKey = hasOwn(target, key);
+ const oldValue = target[key];
+ const result = Reflect.deleteProperty(target, key);
+ if (result && hadKey) {
+ trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
+ }
+ return result;
+ }
+ function has(target, key) {
+ const result = Reflect.has(target, key);
+ if (!isSymbol(key) || !builtInSymbols.has(key)) {
+ track(target, "has" /* HAS */, key);
+ }
+ return result;
+ }
+ function ownKeys(target) {
+ track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
+ return Reflect.ownKeys(target);
+ }
+ const mutableHandlers = {
+ get,
+ set,
+ deleteProperty,
+ has,
+ ownKeys
+ };
+ const readonlyHandlers = {
+ get: readonlyGet,
+ set(target, key) {
+ {
+ console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
+ }
+ return true;
+ },
+ deleteProperty(target, key) {
+ {
+ console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
+ }
+ return true;
+ }
+ };
+ const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
+ get: shallowGet,
+ set: shallowSet
+ });
+ // Props handlers are special in the sense that it should not unwrap top-level
+ // refs (in order to allow refs to be explicitly passed down), but should
+ // retain the reactivity of the normal readonly object.
+ const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
+ get: shallowReadonlyGet
+ });
+
+ const toReactive = (value) => isObject(value) ? reactive(value) : value;
+ const toReadonly = (value) => isObject(value) ? readonly(value) : value;
+ const toShallow = (value) => value;
+ const getProto = (v) => Reflect.getPrototypeOf(v);
+ function get$1(target, key, isReadonly = false, isShallow = false) {
+ // #1772: readonly(reactive(Map)) should return readonly + reactive version
+ // of the value
+ target = target["__v_raw" /* RAW */];
+ const rawTarget = toRaw(target);
+ const rawKey = toRaw(key);
+ if (key !== rawKey) {
+ !isReadonly && track(rawTarget, "get" /* GET */, key);
+ }
+ !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
+ const { has } = getProto(rawTarget);
+ const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
+ if (has.call(rawTarget, key)) {
+ return wrap(target.get(key));
+ }
+ else if (has.call(rawTarget, rawKey)) {
+ return wrap(target.get(rawKey));
+ }
+ else if (target !== rawTarget) {
+ // #3602 readonly(reactive(Map))
+ // ensure that the nested reactive `Map` can do tracking for itself
+ target.get(key);
+ }
+ }
+ function has$1(key, isReadonly = false) {
+ const target = this["__v_raw" /* RAW */];
+ const rawTarget = toRaw(target);
+ const rawKey = toRaw(key);
+ if (key !== rawKey) {
+ !isReadonly && track(rawTarget, "has" /* HAS */, key);
+ }
+ !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
+ return key === rawKey
+ ? target.has(key)
+ : target.has(key) || target.has(rawKey);
+ }
+ function size(target, isReadonly = false) {
+ target = target["__v_raw" /* RAW */];
+ !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
+ return Reflect.get(target, 'size', target);
+ }
+ function add(value) {
+ value = toRaw(value);
+ const target = toRaw(this);
+ const proto = getProto(target);
+ const hadKey = proto.has.call(target, value);
+ if (!hadKey) {
+ target.add(value);
+ trigger(target, "add" /* ADD */, value, value);
+ }
+ return this;
+ }
+ function set$1(key, value) {
+ value = toRaw(value);
+ const target = toRaw(this);
+ const { has, get } = getProto(target);
+ let hadKey = has.call(target, key);
+ if (!hadKey) {
+ key = toRaw(key);
+ hadKey = has.call(target, key);
+ }
+ else {
+ checkIdentityKeys(target, has, key);
+ }
+ const oldValue = get.call(target, key);
+ target.set(key, value);
+ if (!hadKey) {
+ trigger(target, "add" /* ADD */, key, value);
+ }
+ else if (hasChanged(value, oldValue)) {
+ trigger(target, "set" /* SET */, key, value, oldValue);
+ }
+ return this;
+ }
+ function deleteEntry(key) {
+ const target = toRaw(this);
+ const { has, get } = getProto(target);
+ let hadKey = has.call(target, key);
+ if (!hadKey) {
+ key = toRaw(key);
+ hadKey = has.call(target, key);
+ }
+ else {
+ checkIdentityKeys(target, has, key);
+ }
+ const oldValue = get ? get.call(target, key) : undefined;
+ // forward the operation before queueing reactions
+ const result = target.delete(key);
+ if (hadKey) {
+ trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
+ }
+ return result;
+ }
+ function clear() {
+ const target = toRaw(this);
+ const hadItems = target.size !== 0;
+ const oldTarget = isMap(target)
+ ? new Map(target)
+ : new Set(target)
+ ;
+ // forward the operation before queueing reactions
+ const result = target.clear();
+ if (hadItems) {
+ trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
+ }
+ return result;
+ }
+ function createForEach(isReadonly, isShallow) {
+ return function forEach(callback, thisArg) {
+ const observed = this;
+ const target = observed["__v_raw" /* RAW */];
+ const rawTarget = toRaw(target);
+ const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
+ !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
+ return target.forEach((value, key) => {
+ // important: make sure the callback is
+ // 1. invoked with the reactive map as `this` and 3rd arg
+ // 2. the value received should be a corresponding reactive/readonly.
+ return callback.call(thisArg, wrap(value), wrap(key), observed);
+ });
+ };
+ }
+ function createIterableMethod(method, isReadonly, isShallow) {
+ return function (...args) {
+ const target = this["__v_raw" /* RAW */];
+ const rawTarget = toRaw(target);
+ const targetIsMap = isMap(rawTarget);
+ const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
+ const isKeyOnly = method === 'keys' && targetIsMap;
+ const innerIterator = target[method](...args);
+ const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
+ !isReadonly &&
+ track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
+ // return a wrapped iterator which returns observed versions of the
+ // values emitted from the real iterator
+ return {
+ // iterator protocol
+ next() {
+ const { value, done } = innerIterator.next();
+ return done
+ ? { value, done }
+ : {
+ value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
+ done
+ };
+ },
+ // iterable protocol
+ [Symbol.iterator]() {
+ return this;
+ }
+ };
+ };
+ }
+ function createReadonlyMethod(type) {
+ return function (...args) {
+ {
+ const key = args[0] ? `on key "${args[0]}" ` : ``;
+ console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
+ }
+ return type === "delete" /* DELETE */ ? false : this;
+ };
+ }
+ function createInstrumentations() {
+ const mutableInstrumentations = {
+ get(key) {
+ return get$1(this, key);
+ },
+ get size() {
+ return size(this);
+ },
+ has: has$1,
+ add,
+ set: set$1,
+ delete: deleteEntry,
+ clear,
+ forEach: createForEach(false, false)
+ };
+ const shallowInstrumentations = {
+ get(key) {
+ return get$1(this, key, false, true);
+ },
+ get size() {
+ return size(this);
+ },
+ has: has$1,
+ add,
+ set: set$1,
+ delete: deleteEntry,
+ clear,
+ forEach: createForEach(false, true)
+ };
+ const readonlyInstrumentations = {
+ get(key) {
+ return get$1(this, key, true);
+ },
+ get size() {
+ return size(this, true);
+ },
+ has(key) {
+ return has$1.call(this, key, true);
+ },
+ add: createReadonlyMethod("add" /* ADD */),
+ set: createReadonlyMethod("set" /* SET */),
+ delete: createReadonlyMethod("delete" /* DELETE */),
+ clear: createReadonlyMethod("clear" /* CLEAR */),
+ forEach: createForEach(true, false)
+ };
+ const shallowReadonlyInstrumentations = {
+ get(key) {
+ return get$1(this, key, true, true);
+ },
+ get size() {
+ return size(this, true);
+ },
+ has(key) {
+ return has$1.call(this, key, true);
+ },
+ add: createReadonlyMethod("add" /* ADD */),
+ set: createReadonlyMethod("set" /* SET */),
+ delete: createReadonlyMethod("delete" /* DELETE */),
+ clear: createReadonlyMethod("clear" /* CLEAR */),
+ forEach: createForEach(true, true)
+ };
+ const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
+ iteratorMethods.forEach(method => {
+ mutableInstrumentations[method] = createIterableMethod(method, false, false);
+ readonlyInstrumentations[method] = createIterableMethod(method, true, false);
+ shallowInstrumentations[method] = createIterableMethod(method, false, true);
+ shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
+ });
+ return [
+ mutableInstrumentations,
+ readonlyInstrumentations,
+ shallowInstrumentations,
+ shallowReadonlyInstrumentations
+ ];
+ }
+ const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
+ function createInstrumentationGetter(isReadonly, shallow) {
+ const instrumentations = shallow
+ ? isReadonly
+ ? shallowReadonlyInstrumentations
+ : shallowInstrumentations
+ : isReadonly
+ ? readonlyInstrumentations
+ : mutableInstrumentations;
+ return (target, key, receiver) => {
+ if (key === "__v_isReactive" /* IS_REACTIVE */) {
+ return !isReadonly;
+ }
+ else if (key === "__v_isReadonly" /* IS_READONLY */) {
+ return isReadonly;
+ }
+ else if (key === "__v_raw" /* RAW */) {
+ return target;
+ }
+ return Reflect.get(hasOwn(instrumentations, key) && key in target
+ ? instrumentations
+ : target, key, receiver);
+ };
+ }
+ const mutableCollectionHandlers = {
+ get: /*#__PURE__*/ createInstrumentationGetter(false, false)
+ };
+ const shallowCollectionHandlers = {
+ get: /*#__PURE__*/ createInstrumentationGetter(false, true)
+ };
+ const readonlyCollectionHandlers = {
+ get: /*#__PURE__*/ createInstrumentationGetter(true, false)
+ };
+ const shallowReadonlyCollectionHandlers = {
+ get: /*#__PURE__*/ createInstrumentationGetter(true, true)
+ };
+ function checkIdentityKeys(target, has, key) {
+ const rawKey = toRaw(key);
+ if (rawKey !== key && has.call(target, rawKey)) {
+ const type = toRawType(target);
+ console.warn(`Reactive ${type} contains both the raw and reactive ` +
+ `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
+ `which can lead to inconsistencies. ` +
+ `Avoid differentiating between the raw and reactive versions ` +
+ `of an object and only use the reactive version if possible.`);
+ }
+ }
+
+ const reactiveMap = new WeakMap();
+ const shallowReactiveMap = new WeakMap();
+ const readonlyMap = new WeakMap();
+ const shallowReadonlyMap = new WeakMap();
+ function targetTypeMap(rawType) {
+ switch (rawType) {
+ case 'Object':
+ case 'Array':
+ return 1 /* COMMON */;
+ case 'Map':
+ case 'Set':
+ case 'WeakMap':
+ case 'WeakSet':
+ return 2 /* COLLECTION */;
+ default:
+ return 0 /* INVALID */;
+ }
+ }
+ function getTargetType(value) {
+ return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
+ ? 0 /* INVALID */
+ : targetTypeMap(toRawType(value));
+ }
+ function reactive(target) {
+ // if trying to observe a readonly proxy, return the readonly version.
+ if (target && target["__v_isReadonly" /* IS_READONLY */]) {
+ return target;
+ }
+ return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
+ }
+ /**
+ * Return a shallowly-reactive copy of the original object, where only the root
+ * level properties are reactive. It also does not auto-unwrap refs (even at the
+ * root level).
+ */
+ function shallowReactive(target) {
+ return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
+ }
+ /**
+ * Creates a readonly copy of the original object. Note the returned copy is not
+ * made reactive, but `readonly` can be called on an already reactive object.
+ */
+ function readonly(target) {
+ return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
+ }
+ /**
+ * Returns a reactive-copy of the original object, where only the root level
+ * properties are readonly, and does NOT unwrap refs nor recursively convert
+ * returned properties.
+ * This is used for creating the props proxy object for stateful components.
+ */
+ function shallowReadonly(target) {
+ return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
+ }
+ function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
+ if (!isObject(target)) {
+ {
+ console.warn(`value cannot be made reactive: ${String(target)}`);
+ }
+ return target;
+ }
+ // target is already a Proxy, return it.
+ // exception: calling readonly() on a reactive object
+ if (target["__v_raw" /* RAW */] &&
+ !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
+ return target;
+ }
+ // target already has corresponding Proxy
+ const existingProxy = proxyMap.get(target);
+ if (existingProxy) {
+ return existingProxy;
+ }
+ // only a whitelist of value types can be observed.
+ const targetType = getTargetType(target);
+ if (targetType === 0 /* INVALID */) {
+ return target;
+ }
+ const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
+ proxyMap.set(target, proxy);
+ return proxy;
+ }
+ function isReactive(value) {
+ if (isReadonly(value)) {
+ return isReactive(value["__v_raw" /* RAW */]);
+ }
+ return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
+ }
+ function isReadonly(value) {
+ return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
+ }
+ function isProxy(value) {
+ return isReactive(value) || isReadonly(value);
+ }
+ function toRaw(observed) {
+ const raw = observed && observed["__v_raw" /* RAW */];
+ return raw ? toRaw(raw) : observed;
+ }
+ function markRaw(value) {
+ def(value, "__v_skip" /* SKIP */, true);
+ return value;
+ }
+
+ function trackRefValue(ref) {
+ if (isTracking()) {
+ ref = toRaw(ref);
+ if (!ref.dep) {
+ ref.dep = createDep();
+ }
+ {
+ trackEffects(ref.dep, {
+ target: ref,
+ type: "get" /* GET */,
+ key: 'value'
+ });
+ }
+ }
+ }
+ function triggerRefValue(ref, newVal) {
+ ref = toRaw(ref);
+ if (ref.dep) {
+ {
+ triggerEffects(ref.dep, {
+ target: ref,
+ type: "set" /* SET */,
+ key: 'value',
+ newValue: newVal
+ });
+ }
+ }
+ }
+ const convert = (val) => isObject(val) ? reactive(val) : val;
+ function isRef(r) {
+ return Boolean(r && r.__v_isRef === true);
+ }
+ function ref(value) {
+ return createRef(value, false);
+ }
+ function shallowRef(value) {
+ return createRef(value, true);
+ }
+ class RefImpl {
+ constructor(value, _shallow) {
+ this._shallow = _shallow;
+ this.dep = undefined;
+ this.__v_isRef = true;
+ this._rawValue = _shallow ? value : toRaw(value);
+ this._value = _shallow ? value : convert(value);
+ }
+ get value() {
+ trackRefValue(this);
+ return this._value;
+ }
+ set value(newVal) {
+ newVal = this._shallow ? newVal : toRaw(newVal);
+ if (hasChanged(newVal, this._rawValue)) {
+ this._rawValue = newVal;
+ this._value = this._shallow ? newVal : convert(newVal);
+ triggerRefValue(this, newVal);
+ }
+ }
+ }
+ function createRef(rawValue, shallow) {
+ if (isRef(rawValue)) {
+ return rawValue;
+ }
+ return new RefImpl(rawValue, shallow);
+ }
+ function triggerRef(ref) {
+ triggerRefValue(ref, ref.value );
+ }
+ function unref(ref) {
+ return isRef(ref) ? ref.value : ref;
+ }
+ const shallowUnwrapHandlers = {
+ get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
+ set: (target, key, value, receiver) => {
+ const oldValue = target[key];
+ if (isRef(oldValue) && !isRef(value)) {
+ oldValue.value = value;
+ return true;
+ }
+ else {
+ return Reflect.set(target, key, value, receiver);
+ }
+ }
+ };
+ function proxyRefs(objectWithRefs) {
+ return isReactive(objectWithRefs)
+ ? objectWithRefs
+ : new Proxy(objectWithRefs, shallowUnwrapHandlers);
+ }
+ class CustomRefImpl {
+ constructor(factory) {
+ this.dep = undefined;
+ this.__v_isRef = true;
+ const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
+ this._get = get;
+ this._set = set;
+ }
+ get value() {
+ return this._get();
+ }
+ set value(newVal) {
+ this._set(newVal);
+ }
+ }
+ function customRef(factory) {
+ return new CustomRefImpl(factory);
+ }
+ function toRefs(object) {
+ if (!isProxy(object)) {
+ console.warn(`toRefs() expects a reactive object but received a plain one.`);
+ }
+ const ret = isArray(object) ? new Array(object.length) : {};
+ for (const key in object) {
+ ret[key] = toRef(object, key);
+ }
+ return ret;
+ }
+ class ObjectRefImpl {
+ constructor(_object, _key) {
+ this._object = _object;
+ this._key = _key;
+ this.__v_isRef = true;
+ }
+ get value() {
+ return this._object[this._key];
+ }
+ set value(newVal) {
+ this._object[this._key] = newVal;
+ }
+ }
+ function toRef(object, key) {
+ const val = object[key];
+ return isRef(val) ? val : new ObjectRefImpl(object, key);
+ }
+
+ class ComputedRefImpl {
+ constructor(getter, _setter, isReadonly) {
+ this._setter = _setter;
+ this.dep = undefined;
+ this._dirty = true;
+ this.__v_isRef = true;
+ this.effect = new ReactiveEffect(getter, () => {
+ if (!this._dirty) {
+ this._dirty = true;
+ triggerRefValue(this);
+ }
+ });
+ this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
+ }
+ get value() {
+ // the computed ref may get wrapped by other proxies e.g. readonly() #3376
+ const self = toRaw(this);
+ trackRefValue(self);
+ if (self._dirty) {
+ self._dirty = false;
+ self._value = self.effect.run();
+ }
+ return self._value;
+ }
+ set value(newValue) {
+ this._setter(newValue);
+ }
+ }
+ function computed(getterOrOptions, debugOptions) {
+ let getter;
+ let setter;
+ if (isFunction(getterOrOptions)) {
+ getter = getterOrOptions;
+ setter = () => {
+ console.warn('Write operation failed: computed value is readonly');
+ }
+ ;
+ }
+ else {
+ getter = getterOrOptions.get;
+ setter = getterOrOptions.set;
+ }
+ const cRef = new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set);
+ if (debugOptions) {
+ cRef.effect.onTrack = debugOptions.onTrack;
+ cRef.effect.onTrigger = debugOptions.onTrigger;
+ }
+ return cRef;
+ }
+
+ /* eslint-disable no-restricted-globals */
+ let isHmrUpdating = false;
+ const hmrDirtyComponents = new Set();
+ // Expose the HMR runtime on the global object
+ // This makes it entirely tree-shakable without polluting the exports and makes
+ // it easier to be used in toolings like vue-loader
+ // Note: for a component to be eligible for HMR it also needs the __hmrId option
+ // to be set so that its instances can be registered / removed.
+ {
+ const globalObject = typeof global !== 'undefined'
+ ? global
+ : typeof self !== 'undefined'
+ ? self
+ : typeof window !== 'undefined'
+ ? window
+ : {};
+ globalObject.__VUE_HMR_RUNTIME__ = {
+ createRecord: tryWrap(createRecord),
+ rerender: tryWrap(rerender),
+ reload: tryWrap(reload)
+ };
+ }
+ const map = new Map();
+ function registerHMR(instance) {
+ const id = instance.type.__hmrId;
+ let record = map.get(id);
+ if (!record) {
+ createRecord(id);
+ record = map.get(id);
+ }
+ record.add(instance);
+ }
+ function unregisterHMR(instance) {
+ map.get(instance.type.__hmrId).delete(instance);
+ }
+ function createRecord(id) {
+ if (map.has(id)) {
+ return false;
+ }
+ map.set(id, new Set());
+ return true;
+ }
+ function normalizeClassComponent(component) {
+ return isClassComponent(component) ? component.__vccOpts : component;
+ }
+ function rerender(id, newRender) {
+ const record = map.get(id);
+ if (!record) {
+ return;
+ }
+ [...record].forEach(instance => {
+ if (newRender) {
+ instance.render = newRender;
+ normalizeClassComponent(instance.type).render = newRender;
+ }
+ instance.renderCache = [];
+ // this flag forces child components with slot content to update
+ isHmrUpdating = true;
+ instance.update();
+ isHmrUpdating = false;
+ });
+ }
+ function reload(id, newComp) {
+ const record = map.get(id);
+ if (!record)
+ return;
+ newComp = normalizeClassComponent(newComp);
+ // create a snapshot which avoids the set being mutated during updates
+ const instances = [...record];
+ for (const instance of instances) {
+ const oldComp = normalizeClassComponent(instance.type);
+ if (!hmrDirtyComponents.has(oldComp)) {
+ // 1. Update existing comp definition to match new one
+ extend(oldComp, newComp);
+ for (const key in oldComp) {
+ if (key !== '__file' && !(key in newComp)) {
+ delete oldComp[key];
+ }
+ }
+ // 2. mark definition dirty. This forces the renderer to replace the
+ // component on patch.
+ hmrDirtyComponents.add(oldComp);
+ }
+ // 3. invalidate options resolution cache
+ instance.appContext.optionsCache.delete(instance.type);
+ // 4. actually update
+ if (instance.ceReload) {
+ // custom element
+ hmrDirtyComponents.add(oldComp);
+ instance.ceReload(newComp.styles);
+ hmrDirtyComponents.delete(oldComp);
+ }
+ else if (instance.parent) {
+ // 4. Force the parent instance to re-render. This will cause all updated
+ // components to be unmounted and re-mounted. Queue the update so that we
+ // don't end up forcing the same parent to re-render multiple times.
+ queueJob(instance.parent.update);
+ // instance is the inner component of an async custom element
+ // invoke to reset styles
+ if (instance.parent.type.__asyncLoader &&
+ instance.parent.ceReload) {
+ instance.parent.ceReload(newComp.styles);
+ }
+ }
+ else if (instance.appContext.reload) {
+ // root instance mounted via createApp() has a reload method
+ instance.appContext.reload();
+ }
+ else if (typeof window !== 'undefined') {
+ // root instance inside tree created via raw render(). Force reload.
+ window.location.reload();
+ }
+ else {
+ console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
+ }
+ }
+ // 5. make sure to cleanup dirty hmr components after update
+ queuePostFlushCb(() => {
+ for (const instance of instances) {
+ hmrDirtyComponents.delete(normalizeClassComponent(instance.type));
+ }
+ });
+ }
+ function tryWrap(fn) {
+ return (id, arg) => {
+ try {
+ return fn(id, arg);
+ }
+ catch (e) {
+ console.error(e);
+ console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
+ `Full reload required.`);
+ }
+ };
+ }
+
+ function setDevtoolsHook(hook) {
+ exports.devtools = hook;
+ }
+ function devtoolsInitApp(app, version) {
+ // TODO queue if devtools is undefined
+ if (!exports.devtools)
+ return;
+ exports.devtools.emit("app:init" /* APP_INIT */, app, version, {
+ Fragment,
+ Text,
+ Comment,
+ Static
+ });
+ }
+ function devtoolsUnmountApp(app) {
+ if (!exports.devtools)
+ return;
+ exports.devtools.emit("app:unmount" /* APP_UNMOUNT */, app);
+ }
+ const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
+ const devtoolsComponentUpdated =
+ /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
+ const devtoolsComponentRemoved =
+ /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
+ function createDevtoolsComponentHook(hook) {
+ return (component) => {
+ if (!exports.devtools)
+ return;
+ exports.devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
+ };
+ }
+ const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */);
+ const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */);
+ function createDevtoolsPerformanceHook(hook) {
+ return (component, type, time) => {
+ if (!exports.devtools)
+ return;
+ exports.devtools.emit(hook, component.appContext.app, component.uid, component, type, time);
+ };
+ }
+ function devtoolsComponentEmit(component, event, params) {
+ if (!exports.devtools)
+ return;
+ exports.devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
+ }
+
+ const deprecationData = {
+ ["GLOBAL_MOUNT" /* GLOBAL_MOUNT */]: {
+ message: `The global app bootstrapping API has changed: vm.$mount() and the "el" ` +
+ `option have been removed. Use createApp(RootComponent).mount() instead.`,
+ link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance`
+ },
+ ["GLOBAL_MOUNT_CONTAINER" /* GLOBAL_MOUNT_CONTAINER */]: {
+ message: `Vue detected directives on the mount container. ` +
+ `In Vue 3, the container is no longer considered part of the template ` +
+ `and will not be processed/replaced.`,
+ link: `https://v3.vuejs.org/guide/migration/mount-changes.html`
+ },
+ ["GLOBAL_EXTEND" /* GLOBAL_EXTEND */]: {
+ message: `Vue.extend() has been removed in Vue 3. ` +
+ `Use defineComponent() instead.`,
+ link: `https://v3.vuejs.org/api/global-api.html#definecomponent`
+ },
+ ["GLOBAL_PROTOTYPE" /* GLOBAL_PROTOTYPE */]: {
+ message: `Vue.prototype is no longer available in Vue 3. ` +
+ `Use app.config.globalProperties instead.`,
+ link: `https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties`
+ },
+ ["GLOBAL_SET" /* GLOBAL_SET */]: {
+ message: `Vue.set() has been removed as it is no longer needed in Vue 3. ` +
+ `Simply use native JavaScript mutations.`
+ },
+ ["GLOBAL_DELETE" /* GLOBAL_DELETE */]: {
+ message: `Vue.delete() has been removed as it is no longer needed in Vue 3. ` +
+ `Simply use native JavaScript mutations.`
+ },
+ ["GLOBAL_OBSERVABLE" /* GLOBAL_OBSERVABLE */]: {
+ message: `Vue.observable() has been removed. ` +
+ `Use \`import { reactive } from "vue"\` from Composition API instead.`,
+ link: `https://v3.vuejs.org/api/basic-reactivity.html`
+ },
+ ["GLOBAL_PRIVATE_UTIL" /* GLOBAL_PRIVATE_UTIL */]: {
+ message: `Vue.util has been removed. Please refactor to avoid its usage ` +
+ `since it was an internal API even in Vue 2.`
+ },
+ ["CONFIG_SILENT" /* CONFIG_SILENT */]: {
+ message: `config.silent has been removed because it is not good practice to ` +
+ `intentionally suppress warnings. You can use your browser console's ` +
+ `filter features to focus on relevant messages.`
+ },
+ ["CONFIG_DEVTOOLS" /* CONFIG_DEVTOOLS */]: {
+ message: `config.devtools has been removed. To enable devtools for ` +
+ `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`,
+ link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags`
+ },
+ ["CONFIG_KEY_CODES" /* CONFIG_KEY_CODES */]: {
+ message: `config.keyCodes has been removed. ` +
+ `In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`,
+ link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
+ },
+ ["CONFIG_PRODUCTION_TIP" /* CONFIG_PRODUCTION_TIP */]: {
+ message: `config.productionTip has been removed.`,
+ link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed`
+ },
+ ["CONFIG_IGNORED_ELEMENTS" /* CONFIG_IGNORED_ELEMENTS */]: {
+ message: () => {
+ let msg = `config.ignoredElements has been removed.`;
+ if (isRuntimeOnly()) {
+ msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.`;
+ }
+ else {
+ msg += ` Use config.isCustomElement instead.`;
+ }
+ return msg;
+ },
+ link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement`
+ },
+ ["CONFIG_WHITESPACE" /* CONFIG_WHITESPACE */]: {
+ // this warning is only relevant in the full build when using runtime
+ // compilation, so it's put in the runtime compatConfig list.
+ message: `Vue 3 compiler's whitespace option will default to "condense" instead of ` +
+ `"preserve". To suppress this warning, provide an explicit value for ` +
+ `\`config.compilerOptions.whitespace\`.`
+ },
+ ["CONFIG_OPTION_MERGE_STRATS" /* CONFIG_OPTION_MERGE_STRATS */]: {
+ message: `config.optionMergeStrategies no longer exposes internal strategies. ` +
+ `Use custom merge functions instead.`
+ },
+ ["INSTANCE_SET" /* INSTANCE_SET */]: {
+ message: `vm.$set() has been removed as it is no longer needed in Vue 3. ` +
+ `Simply use native JavaScript mutations.`
+ },
+ ["INSTANCE_DELETE" /* INSTANCE_DELETE */]: {
+ message: `vm.$delete() has been removed as it is no longer needed in Vue 3. ` +
+ `Simply use native JavaScript mutations.`
+ },
+ ["INSTANCE_DESTROY" /* INSTANCE_DESTROY */]: {
+ message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
+ link: `https://v3.vuejs.org/api/application-api.html#unmount`
+ },
+ ["INSTANCE_EVENT_EMITTER" /* INSTANCE_EVENT_EMITTER */]: {
+ message: `vm.$on/$once/$off() have been removed. ` +
+ `Use an external event emitter library instead.`,
+ link: `https://v3.vuejs.org/guide/migration/events-api.html`
+ },
+ ["INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */]: {
+ message: event => `"${event}" lifecycle events are no longer supported. From templates, ` +
+ `use the "vnode" prefix instead of "hook:". For example, @${event} ` +
+ `should be changed to @vnode-${event.slice(5)}. ` +
+ `From JavaScript, use Composition API to dynamically register lifecycle ` +
+ `hooks.`,
+ link: `https://v3.vuejs.org/guide/migration/vnode-lifecycle-events.html`
+ },
+ ["INSTANCE_CHILDREN" /* INSTANCE_CHILDREN */]: {
+ message: `vm.$children has been removed. Consider refactoring your logic ` +
+ `to avoid relying on direct access to child components.`,
+ link: `https://v3.vuejs.org/guide/migration/children.html`
+ },
+ ["INSTANCE_LISTENERS" /* INSTANCE_LISTENERS */]: {
+ message: `vm.$listeners has been removed. In Vue 3, parent v-on listeners are ` +
+ `included in vm.$attrs and it is no longer necessary to separately use ` +
+ `v-on="$listeners" if you are already using v-bind="$attrs". ` +
+ `(Note: the Vue 3 behavior only applies if this compat config is disabled)`,
+ link: `https://v3.vuejs.org/guide/migration/listeners-removed.html`
+ },
+ ["INSTANCE_SCOPED_SLOTS" /* INSTANCE_SCOPED_SLOTS */]: {
+ message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`,
+ link: `https://v3.vuejs.org/guide/migration/slots-unification.html`
+ },
+ ["INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */]: {
+ message: componentName => `Component <${componentName || 'Anonymous'}> has \`inheritAttrs: false\` but is ` +
+ `relying on class/style fallthrough from parent. In Vue 3, class/style ` +
+ `are now included in $attrs and will no longer fallthrough when ` +
+ `inheritAttrs is false. If you are already using v-bind="$attrs" on ` +
+ `component root it should render the same end result. ` +
+ `If you are binding $attrs to a non-root element and expecting ` +
+ `class/style to fallthrough on root, you will need to now manually bind ` +
+ `them on root via :class="$attrs.class".`,
+ link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html`
+ },
+ ["OPTIONS_DATA_FN" /* OPTIONS_DATA_FN */]: {
+ message: `The "data" option can no longer be a plain object. ` +
+ `Always use a function.`,
+ link: `https://v3.vuejs.org/guide/migration/data-option.html`
+ },
+ ["OPTIONS_DATA_MERGE" /* OPTIONS_DATA_MERGE */]: {
+ message: (key) => `Detected conflicting key "${key}" when merging data option values. ` +
+ `In Vue 3, data keys are merged shallowly and will override one another.`,
+ link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change`
+ },
+ ["OPTIONS_BEFORE_DESTROY" /* OPTIONS_BEFORE_DESTROY */]: {
+ message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`
+ },
+ ["OPTIONS_DESTROYED" /* OPTIONS_DESTROYED */]: {
+ message: `\`destroyed\` has been renamed to \`unmounted\`.`
+ },
+ ["WATCH_ARRAY" /* WATCH_ARRAY */]: {
+ message: `"watch" option or vm.$watch on an array value will no longer ` +
+ `trigger on array mutation unless the "deep" option is specified. ` +
+ `If current usage is intended, you can disable the compat behavior and ` +
+ `suppress this warning with:` +
+ `\n\n configureCompat({ ${"WATCH_ARRAY" /* WATCH_ARRAY */}: false })\n`,
+ link: `https://v3.vuejs.org/guide/migration/watch.html`
+ },
+ ["PROPS_DEFAULT_THIS" /* PROPS_DEFAULT_THIS */]: {
+ message: (key) => `props default value function no longer has access to "this". The compat ` +
+ `build only offers access to this.$options.` +
+ `(found in prop "${key}")`,
+ link: `https://v3.vuejs.org/guide/migration/props-default-this.html`
+ },
+ ["CUSTOM_DIR" /* CUSTOM_DIR */]: {
+ message: (legacyHook, newHook) => `Custom directive hook "${legacyHook}" has been removed. ` +
+ `Use "${newHook}" instead.`,
+ link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
+ },
+ ["V_FOR_REF" /* V_FOR_REF */]: {
+ message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
+ `Consider using function refs or refactor to avoid ref usage altogether.`,
+ link: `https://v3.vuejs.org/guide/migration/array-refs.html`
+ },
+ ["V_ON_KEYCODE_MODIFIER" /* V_ON_KEYCODE_MODIFIER */]: {
+ message: `Using keyCode as v-on modifier is no longer supported. ` +
+ `Use kebab-case key name modifiers instead.`,
+ link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
+ },
+ ["ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */]: {
+ message: (name) => `Attribute "${name}" with v-bind value \`false\` will render ` +
+ `${name}="false" instead of removing it in Vue 3. To remove the attribute, ` +
+ `use \`null\` or \`undefined\` instead. If the usage is intended, ` +
+ `you can disable the compat behavior and suppress this warning with:` +
+ `\n\n configureCompat({ ${"ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */}: false })\n`,
+ link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
+ },
+ ["ATTR_ENUMERATED_COERCION" /* ATTR_ENUMERATED_COERCION */]: {
+ message: (name, value, coerced) => `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` +
+ `${value === null ? `be removed` : `render the value as-is`} instead of coercing the value to "${coerced}" in Vue 3. ` +
+ `Always use explicit "true" or "false" values for enumerated attributes. ` +
+ `If the usage is intended, ` +
+ `you can disable the compat behavior and suppress this warning with:` +
+ `\n\n configureCompat({ ${"ATTR_ENUMERATED_COERCION" /* ATTR_ENUMERATED_COERCION */}: false })\n`,
+ link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
+ },
+ ["TRANSITION_CLASSES" /* TRANSITION_CLASSES */]: {
+ message: `` // this feature cannot be runtime-detected
+ },
+ ["TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */]: {
+ message: ` no longer renders a root element by ` +
+ `default if no "tag" prop is specified. If you do not rely on the span ` +
+ `for styling, you can disable the compat behavior and suppress this ` +
+ `warning with:` +
+ `\n\n configureCompat({ ${"TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */}: false })\n`,
+ link: `https://v3.vuejs.org/guide/migration/transition-group.html`
+ },
+ ["COMPONENT_ASYNC" /* COMPONENT_ASYNC */]: {
+ message: (comp) => {
+ const name = getComponentName(comp);
+ return (`Async component${name ? ` <${name}>` : `s`} should be explicitly created via \`defineAsyncComponent()\` ` +
+ `in Vue 3. Plain functions will be treated as functional components in ` +
+ `non-compat build. If you have already migrated all async component ` +
+ `usage and intend to use plain functions for functional components, ` +
+ `you can disable the compat behavior and suppress this ` +
+ `warning with:` +
+ `\n\n configureCompat({ ${"COMPONENT_ASYNC" /* COMPONENT_ASYNC */}: false })\n`);
+ },
+ link: `https://v3.vuejs.org/guide/migration/async-components.html`
+ },
+ ["COMPONENT_FUNCTIONAL" /* COMPONENT_FUNCTIONAL */]: {
+ message: (comp) => {
+ const name = getComponentName(comp);
+ return (`Functional component${name ? ` <${name}>` : `s`} should be defined as a plain function in Vue 3. The "functional" ` +
+ `option has been removed. NOTE: Before migrating to use plain ` +
+ `functions for functional components, first make sure that all async ` +
+ `components usage have been migrated and its compat behavior has ` +
+ `been disabled.`);
+ },
+ link: `https://v3.vuejs.org/guide/migration/functional-components.html`
+ },
+ ["COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */]: {
+ message: (comp) => {
+ const configMsg = `opt-in to ` +
+ `Vue 3 behavior on a per-component basis with \`compatConfig: { ${"COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */}: false }\`.`;
+ if (comp.props &&
+ (isArray(comp.props)
+ ? comp.props.includes('modelValue')
+ : hasOwn(comp.props, 'modelValue'))) {
+ return (`Component delcares "modelValue" prop, which is Vue 3 usage, but ` +
+ `is running under Vue 2 compat v-model behavior. You can ${configMsg}`);
+ }
+ return (`v-model usage on component has changed in Vue 3. Component that expects ` +
+ `to work with v-model should now use the "modelValue" prop and emit the ` +
+ `"update:modelValue" event. You can update the usage and then ${configMsg}`);
+ },
+ link: `https://v3.vuejs.org/guide/migration/v-model.html`
+ },
+ ["RENDER_FUNCTION" /* RENDER_FUNCTION */]: {
+ message: `Vue 3's render function API has changed. ` +
+ `You can opt-in to the new API with:` +
+ `\n\n configureCompat({ ${"RENDER_FUNCTION" /* RENDER_FUNCTION */}: false })\n` +
+ `\n (This can also be done per-component via the "compatConfig" option.)`,
+ link: `https://v3.vuejs.org/guide/migration/render-function-api.html`
+ },
+ ["FILTERS" /* FILTERS */]: {
+ message: `filters have been removed in Vue 3. ` +
+ `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
+ `Use method calls or computed properties instead.`,
+ link: `https://v3.vuejs.org/guide/migration/filters.html`
+ },
+ ["PRIVATE_APIS" /* PRIVATE_APIS */]: {
+ message: name => `"${name}" is a Vue 2 private API that no longer exists in Vue 3. ` +
+ `If you are seeing this warning only due to a dependency, you can ` +
+ `suppress this warning via { PRIVATE_APIS: 'supress-warning' }.`
+ }
+ };
+ const instanceWarned = Object.create(null);
+ const warnCount = Object.create(null);
+ function warnDeprecation(key, instance, ...args) {
+ instance = instance || getCurrentInstance();
+ // check user config
+ const config = getCompatConfigForKey(key, instance);
+ if (config === 'suppress-warning') {
+ return;
+ }
+ const dupKey = key + args.join('');
+ let compId = instance && formatComponentName(instance, instance.type);
+ if (compId === 'Anonymous' && instance) {
+ compId = instance.uid;
+ }
+ // skip if the same warning is emitted for the same component type
+ const componentDupKey = dupKey + compId;
+ if (componentDupKey in instanceWarned) {
+ return;
+ }
+ instanceWarned[componentDupKey] = true;
+ // same warning, but different component. skip the long message and just
+ // log the key and count.
+ if (dupKey in warnCount) {
+ warn$1(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`);
+ return;
+ }
+ warnCount[dupKey] = 0;
+ const { message, link } = deprecationData[key];
+ warn$1(`(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`);
+ if (!isCompatEnabled(key, instance, true)) {
+ console.error(`^ The above deprecation's compat behavior is disabled and will likely ` +
+ `lead to runtime errors.`);
+ }
+ }
+ const globalCompatConfig = {
+ MODE: 2
+ };
+ function getCompatConfigForKey(key, instance) {
+ const instanceConfig = instance && instance.type.compatConfig;
+ if (instanceConfig && key in instanceConfig) {
+ return instanceConfig[key];
+ }
+ return globalCompatConfig[key];
+ }
+ function isCompatEnabled(key, instance, enableForBuiltIn = false) {
+ // skip compat for built-in components
+ if (!enableForBuiltIn && instance && instance.type.__isBuiltIn) {
+ return false;
+ }
+ const rawMode = getCompatConfigForKey('MODE', instance) || 2;
+ const val = getCompatConfigForKey(key, instance);
+ const mode = isFunction(rawMode)
+ ? rawMode(instance && instance.type)
+ : rawMode;
+ if (mode === 2) {
+ return val !== false;
+ }
+ else {
+ return val === true || val === 'suppress-warning';
+ }
+ }
+
+ function emit(instance, event, ...rawArgs) {
+ const props = instance.vnode.props || EMPTY_OBJ;
+ {
+ const { emitsOptions, propsOptions: [propsOptions] } = instance;
+ if (emitsOptions) {
+ if (!(event in emitsOptions) &&
+ !(false )) {
+ if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
+ warn$1(`Component emitted event "${event}" but it is neither declared in ` +
+ `the emits option nor as an "${toHandlerKey(event)}" prop.`);
+ }
+ }
+ else {
+ const validator = emitsOptions[event];
+ if (isFunction(validator)) {
+ const isValid = validator(...rawArgs);
+ if (!isValid) {
+ warn$1(`Invalid event arguments: event validation failed for event "${event}".`);
+ }
+ }
+ }
+ }
+ }
+ let args = rawArgs;
+ const isModelListener = event.startsWith('update:');
+ // for v-model update:xxx events, apply modifiers on args
+ const modelArg = isModelListener && event.slice(7);
+ if (modelArg && modelArg in props) {
+ const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
+ const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
+ if (trim) {
+ args = rawArgs.map(a => a.trim());
+ }
+ else if (number) {
+ args = rawArgs.map(toNumber);
+ }
+ }
+ {
+ devtoolsComponentEmit(instance, event, args);
+ }
+ {
+ const lowerCaseEvent = event.toLowerCase();
+ if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
+ warn$1(`Event "${lowerCaseEvent}" is emitted in component ` +
+ `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
+ `Note that HTML attributes are case-insensitive and you cannot use ` +
+ `v-on to listen to camelCase events when using in-DOM templates. ` +
+ `You should probably use "${hyphenate(event)}" instead of "${event}".`);
+ }
+ }
+ let handlerName;
+ let handler = props[(handlerName = toHandlerKey(event))] ||
+ // also try camelCase event handler (#2249)
+ props[(handlerName = toHandlerKey(camelize(event)))];
+ // for v-model update:xxx events, also trigger kebab-case equivalent
+ // for props passed via kebab-case
+ if (!handler && isModelListener) {
+ handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
+ }
+ if (handler) {
+ callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ }
+ const onceHandler = props[handlerName + `Once`];
+ if (onceHandler) {
+ if (!instance.emitted) {
+ instance.emitted = {};
+ }
+ else if (instance.emitted[handlerName]) {
+ return;
+ }
+ instance.emitted[handlerName] = true;
+ callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ }
+ }
+ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
+ const cache = appContext.emitsCache;
+ const cached = cache.get(comp);
+ if (cached !== undefined) {
+ return cached;
+ }
+ const raw = comp.emits;
+ let normalized = {};
+ // apply mixin/extends props
+ let hasExtends = false;
+ if (!isFunction(comp)) {
+ const extendEmits = (raw) => {
+ const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
+ if (normalizedFromExtend) {
+ hasExtends = true;
+ extend(normalized, normalizedFromExtend);
+ }
+ };
+ if (!asMixin && appContext.mixins.length) {
+ appContext.mixins.forEach(extendEmits);
+ }
+ if (comp.extends) {
+ extendEmits(comp.extends);
+ }
+ if (comp.mixins) {
+ comp.mixins.forEach(extendEmits);
+ }
+ }
+ if (!raw && !hasExtends) {
+ cache.set(comp, null);
+ return null;
+ }
+ if (isArray(raw)) {
+ raw.forEach(key => (normalized[key] = null));
+ }
+ else {
+ extend(normalized, raw);
+ }
+ cache.set(comp, normalized);
+ return normalized;
+ }
+ // Check if an incoming prop key is a declared emit event listener.
+ // e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
+ // both considered matched listeners.
+ function isEmitListener(options, key) {
+ if (!options || !isOn(key)) {
+ return false;
+ }
+ key = key.slice(2).replace(/Once$/, '');
+ return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
+ hasOwn(options, hyphenate(key)) ||
+ hasOwn(options, key));
+ }
+
+ /**
+ * mark the current rendering instance for asset resolution (e.g.
+ * resolveComponent, resolveDirective) during render
+ */
+ let currentRenderingInstance = null;
+ let currentScopeId = null;
+ /**
+ * Note: rendering calls maybe nested. The function returns the parent rendering
+ * instance if present, which should be restored after the render is done:
+ *
+ * ```js
+ * const prev = setCurrentRenderingInstance(i)
+ * // ...render
+ * setCurrentRenderingInstance(prev)
+ * ```
+ */
+ function setCurrentRenderingInstance(instance) {
+ const prev = currentRenderingInstance;
+ currentRenderingInstance = instance;
+ currentScopeId = (instance && instance.type.__scopeId) || null;
+ return prev;
+ }
+ /**
+ * Set scope id when creating hoisted vnodes.
+ * @private compiler helper
+ */
+ function pushScopeId(id) {
+ currentScopeId = id;
+ }
+ /**
+ * Technically we no longer need this after 3.0.8 but we need to keep the same
+ * API for backwards compat w/ code generated by compilers.
+ * @private
+ */
+ function popScopeId() {
+ currentScopeId = null;
+ }
+ /**
+ * Only for backwards compat
+ * @private
+ */
+ const withScopeId = (_id) => withCtx;
+ /**
+ * Wrap a slot function to memoize current rendering instance
+ * @private compiler helper
+ */
+ function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
+ ) {
+ if (!ctx)
+ return fn;
+ // already normalized
+ if (fn._n) {
+ return fn;
+ }
+ const renderFnWithContext = (...args) => {
+ // If a user calls a compiled slot inside a template expression (#1745), it
+ // can mess up block tracking, so by default we disable block tracking and
+ // force bail out when invoking a compiled slot (indicated by the ._d flag).
+ // This isn't necessary if rendering a compiled ``, so we flip the
+ // ._d flag off when invoking the wrapped fn inside `renderSlot`.
+ if (renderFnWithContext._d) {
+ setBlockTracking(-1);
+ }
+ const prevInstance = setCurrentRenderingInstance(ctx);
+ const res = fn(...args);
+ setCurrentRenderingInstance(prevInstance);
+ if (renderFnWithContext._d) {
+ setBlockTracking(1);
+ }
+ {
+ devtoolsComponentUpdated(ctx);
+ }
+ return res;
+ };
+ // mark normalized to avoid duplicated wrapping
+ renderFnWithContext._n = true;
+ // mark this as compiled by default
+ // this is used in vnode.ts -> normalizeChildren() to set the slot
+ // rendering flag.
+ renderFnWithContext._c = true;
+ // disable block tracking by default
+ renderFnWithContext._d = true;
+ return renderFnWithContext;
+ }
+
+ /**
+ * dev only flag to track whether $attrs was used during render.
+ * If $attrs was used during render then the warning for failed attrs
+ * fallthrough can be suppressed.
+ */
+ let accessedAttrs = false;
+ function markAttrsAccessed() {
+ accessedAttrs = true;
+ }
+ function renderComponentRoot(instance) {
+ const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
+ let result;
+ const prev = setCurrentRenderingInstance(instance);
+ {
+ accessedAttrs = false;
+ }
+ try {
+ let fallthroughAttrs;
+ if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
+ // withProxy is a proxy with a different `has` trap only for
+ // runtime-compiled render functions using `with` block.
+ const proxyToUse = withProxy || proxy;
+ result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
+ fallthroughAttrs = attrs;
+ }
+ else {
+ // functional
+ const render = Component;
+ // in dev, mark attrs accessed if optional props (attrs === props)
+ if (true && attrs === props) {
+ markAttrsAccessed();
+ }
+ result = normalizeVNode(render.length > 1
+ ? render(props, true
+ ? {
+ get attrs() {
+ markAttrsAccessed();
+ return attrs;
+ },
+ slots,
+ emit
+ }
+ : { attrs, slots, emit })
+ : render(props, null /* we know it doesn't need it */));
+ fallthroughAttrs = Component.props
+ ? attrs
+ : getFunctionalFallthrough(attrs);
+ }
+ // attr merging
+ // in dev mode, comments are preserved, and it's possible for a template
+ // to have comments along side the root element which makes it a fragment
+ let root = result;
+ let setRoot = undefined;
+ if (true &&
+ result.patchFlag > 0 &&
+ result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
+ ;
+ [root, setRoot] = getChildRoot(result);
+ }
+ if (fallthroughAttrs && inheritAttrs !== false) {
+ const keys = Object.keys(fallthroughAttrs);
+ const { shapeFlag } = root;
+ if (keys.length) {
+ if (shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) {
+ if (propsOptions && keys.some(isModelListener)) {
+ // If a v-model listener (onUpdate:xxx) has a corresponding declared
+ // prop, it indicates this component expects to handle v-model and
+ // it should not fallthrough.
+ // related: #1543, #1643, #1989
+ fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
+ }
+ root = cloneVNode(root, fallthroughAttrs);
+ }
+ else if (true && !accessedAttrs && root.type !== Comment) {
+ const allAttrs = Object.keys(attrs);
+ const eventAttrs = [];
+ const extraAttrs = [];
+ for (let i = 0, l = allAttrs.length; i < l; i++) {
+ const key = allAttrs[i];
+ if (isOn(key)) {
+ // ignore v-model handlers when they fail to fallthrough
+ if (!isModelListener(key)) {
+ // remove `on`, lowercase first letter to reflect event casing
+ // accurately
+ eventAttrs.push(key[2].toLowerCase() + key.slice(3));
+ }
+ }
+ else {
+ extraAttrs.push(key);
+ }
+ }
+ if (extraAttrs.length) {
+ warn$1(`Extraneous non-props attributes (` +
+ `${extraAttrs.join(', ')}) ` +
+ `were passed to component but could not be automatically inherited ` +
+ `because component renders fragment or text root nodes.`);
+ }
+ if (eventAttrs.length) {
+ warn$1(`Extraneous non-emits event listeners (` +
+ `${eventAttrs.join(', ')}) ` +
+ `were passed to component but could not be automatically inherited ` +
+ `because component renders fragment or text root nodes. ` +
+ `If the listener is intended to be a component custom event listener only, ` +
+ `declare it using the "emits" option.`);
+ }
+ }
+ }
+ }
+ if (false &&
+ isCompatEnabled("INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */, instance) &&
+ vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */ &&
+ root.shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) ;
+ // inherit directives
+ if (vnode.dirs) {
+ if (true && !isElementRoot(root)) {
+ warn$1(`Runtime directive used on component with non-element root node. ` +
+ `The directives will not function as intended.`);
+ }
+ root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
+ }
+ // inherit transition data
+ if (vnode.transition) {
+ if (true && !isElementRoot(root)) {
+ warn$1(`Component inside renders non-element root node ` +
+ `that cannot be animated.`);
+ }
+ root.transition = vnode.transition;
+ }
+ if (true && setRoot) {
+ setRoot(root);
+ }
+ else {
+ result = root;
+ }
+ }
+ catch (err) {
+ blockStack.length = 0;
+ handleError(err, instance, 1 /* RENDER_FUNCTION */);
+ result = createVNode(Comment);
+ }
+ setCurrentRenderingInstance(prev);
+ return result;
+ }
+ /**
+ * dev only
+ * In dev mode, template root level comments are rendered, which turns the
+ * template into a fragment root, but we need to locate the single element
+ * root for attrs and scope id processing.
+ */
+ const getChildRoot = (vnode) => {
+ const rawChildren = vnode.children;
+ const dynamicChildren = vnode.dynamicChildren;
+ const childRoot = filterSingleRoot(rawChildren);
+ if (!childRoot) {
+ return [vnode, undefined];
+ }
+ const index = rawChildren.indexOf(childRoot);
+ const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
+ const setRoot = (updatedRoot) => {
+ rawChildren[index] = updatedRoot;
+ if (dynamicChildren) {
+ if (dynamicIndex > -1) {
+ dynamicChildren[dynamicIndex] = updatedRoot;
+ }
+ else if (updatedRoot.patchFlag > 0) {
+ vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
+ }
+ }
+ };
+ return [normalizeVNode(childRoot), setRoot];
+ };
+ function filterSingleRoot(children) {
+ let singleRoot;
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i];
+ if (isVNode(child)) {
+ // ignore user comment
+ if (child.type !== Comment || child.children === 'v-if') {
+ if (singleRoot) {
+ // has more than 1 non-comment child, return now
+ return;
+ }
+ else {
+ singleRoot = child;
+ }
+ }
+ }
+ else {
+ return;
+ }
+ }
+ return singleRoot;
+ }
+ const getFunctionalFallthrough = (attrs) => {
+ let res;
+ for (const key in attrs) {
+ if (key === 'class' || key === 'style' || isOn(key)) {
+ (res || (res = {}))[key] = attrs[key];
+ }
+ }
+ return res;
+ };
+ const filterModelListeners = (attrs, props) => {
+ const res = {};
+ for (const key in attrs) {
+ if (!isModelListener(key) || !(key.slice(9) in props)) {
+ res[key] = attrs[key];
+ }
+ }
+ return res;
+ };
+ const isElementRoot = (vnode) => {
+ return (vnode.shapeFlag & (6 /* COMPONENT */ | 1 /* ELEMENT */) ||
+ vnode.type === Comment // potential v-if branch switch
+ );
+ };
+ function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
+ const { props: prevProps, children: prevChildren, component } = prevVNode;
+ const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
+ const emits = component.emitsOptions;
+ // Parent component's render function was hot-updated. Since this may have
+ // caused the child component's slots content to have changed, we need to
+ // force the child to update as well.
+ if ((prevChildren || nextChildren) && isHmrUpdating) {
+ return true;
+ }
+ // force child update for runtime directive or transition on component vnode.
+ if (nextVNode.dirs || nextVNode.transition) {
+ return true;
+ }
+ if (optimized && patchFlag >= 0) {
+ if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
+ // slot content that references values that might have changed,
+ // e.g. in a v-for
+ return true;
+ }
+ if (patchFlag & 16 /* FULL_PROPS */) {
+ if (!prevProps) {
+ return !!nextProps;
+ }
+ // presence of this flag indicates props are always non-null
+ return hasPropsChanged(prevProps, nextProps, emits);
+ }
+ else if (patchFlag & 8 /* PROPS */) {
+ const dynamicProps = nextVNode.dynamicProps;
+ for (let i = 0; i < dynamicProps.length; i++) {
+ const key = dynamicProps[i];
+ if (nextProps[key] !== prevProps[key] &&
+ !isEmitListener(emits, key)) {
+ return true;
+ }
+ }
+ }
+ }
+ else {
+ // this path is only taken by manually written render functions
+ // so presence of any children leads to a forced update
+ if (prevChildren || nextChildren) {
+ if (!nextChildren || !nextChildren.$stable) {
+ return true;
+ }
+ }
+ if (prevProps === nextProps) {
+ return false;
+ }
+ if (!prevProps) {
+ return !!nextProps;
+ }
+ if (!nextProps) {
+ return true;
+ }
+ return hasPropsChanged(prevProps, nextProps, emits);
+ }
+ return false;
+ }
+ function hasPropsChanged(prevProps, nextProps, emitsOptions) {
+ const nextKeys = Object.keys(nextProps);
+ if (nextKeys.length !== Object.keys(prevProps).length) {
+ return true;
+ }
+ for (let i = 0; i < nextKeys.length; i++) {
+ const key = nextKeys[i];
+ if (nextProps[key] !== prevProps[key] &&
+ !isEmitListener(emitsOptions, key)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ function updateHOCHostEl({ vnode, parent }, el // HostNode
+ ) {
+ while (parent && parent.subTree === vnode) {
+ (vnode = parent.vnode).el = el;
+ parent = parent.parent;
+ }
+ }
+
+ const isSuspense = (type) => type.__isSuspense;
+ // Suspense exposes a component-like API, and is treated like a component
+ // in the compiler, but internally it's a special built-in type that hooks
+ // directly into the renderer.
+ const SuspenseImpl = {
+ name: 'Suspense',
+ // In order to make Suspense tree-shakable, we need to avoid importing it
+ // directly in the renderer. The renderer checks for the __isSuspense flag
+ // on a vnode's type and calls the `process` method, passing in renderer
+ // internals.
+ __isSuspense: true,
+ process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
+ // platform-specific impl passed from renderer
+ rendererInternals) {
+ if (n1 == null) {
+ mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
+ }
+ else {
+ patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
+ }
+ },
+ hydrate: hydrateSuspense,
+ create: createSuspenseBoundary,
+ normalize: normalizeSuspenseChildren
+ };
+ // Force-casted public typing for h and TSX props inference
+ const Suspense = (SuspenseImpl );
+ function triggerEvent(vnode, name) {
+ const eventListener = vnode.props && vnode.props[name];
+ if (isFunction(eventListener)) {
+ eventListener();
+ }
+ }
+ function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
+ const { p: patch, o: { createElement } } = rendererInternals;
+ const hiddenContainer = createElement('div');
+ const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
+ // start mounting the content subtree in an off-dom container
+ patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
+ // now check if we have encountered any async deps
+ if (suspense.deps > 0) {
+ // has async
+ // invoke @fallback event
+ triggerEvent(vnode, 'onPending');
+ triggerEvent(vnode, 'onFallback');
+ // mount the fallback tree
+ patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
+ isSVG, slotScopeIds);
+ setActiveBranch(suspense, vnode.ssFallback);
+ }
+ else {
+ // Suspense has no async deps. Just resolve.
+ suspense.resolve();
+ }
+ }
+ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
+ const suspense = (n2.suspense = n1.suspense);
+ suspense.vnode = n2;
+ n2.el = n1.el;
+ const newBranch = n2.ssContent;
+ const newFallback = n2.ssFallback;
+ const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
+ if (pendingBranch) {
+ suspense.pendingBranch = newBranch;
+ if (isSameVNodeType(newBranch, pendingBranch)) {
+ // same root type but content may have changed.
+ patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
+ if (suspense.deps <= 0) {
+ suspense.resolve();
+ }
+ else if (isInFallback) {
+ patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
+ isSVG, slotScopeIds, optimized);
+ setActiveBranch(suspense, newFallback);
+ }
+ }
+ else {
+ // toggled before pending tree is resolved
+ suspense.pendingId++;
+ if (isHydrating) {
+ // if toggled before hydration is finished, the current DOM tree is
+ // no longer valid. set it as the active branch so it will be unmounted
+ // when resolved
+ suspense.isHydrating = false;
+ suspense.activeBranch = pendingBranch;
+ }
+ else {
+ unmount(pendingBranch, parentComponent, suspense);
+ }
+ // increment pending ID. this is used to invalidate async callbacks
+ // reset suspense state
+ suspense.deps = 0;
+ // discard effects from pending branch
+ suspense.effects.length = 0;
+ // discard previous container
+ suspense.hiddenContainer = createElement('div');
+ if (isInFallback) {
+ // already in fallback state
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
+ if (suspense.deps <= 0) {
+ suspense.resolve();
+ }
+ else {
+ patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
+ isSVG, slotScopeIds, optimized);
+ setActiveBranch(suspense, newFallback);
+ }
+ }
+ else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
+ // toggled "back" to current active branch
+ patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
+ // force resolve
+ suspense.resolve(true);
+ }
+ else {
+ // switched to a 3rd branch
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
+ if (suspense.deps <= 0) {
+ suspense.resolve();
+ }
+ }
+ }
+ }
+ else {
+ if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
+ // root did not change, just normal patch
+ patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
+ setActiveBranch(suspense, newBranch);
+ }
+ else {
+ // root node toggled
+ // invoke @pending event
+ triggerEvent(n2, 'onPending');
+ // mount pending branch in off-dom container
+ suspense.pendingBranch = newBranch;
+ suspense.pendingId++;
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
+ if (suspense.deps <= 0) {
+ // incoming branch has no async deps, resolve now.
+ suspense.resolve();
+ }
+ else {
+ const { timeout, pendingId } = suspense;
+ if (timeout > 0) {
+ setTimeout(() => {
+ if (suspense.pendingId === pendingId) {
+ suspense.fallback(newFallback);
+ }
+ }, timeout);
+ }
+ else if (timeout === 0) {
+ suspense.fallback(newFallback);
+ }
+ }
+ }
+ }
+ }
+ let hasWarned = false;
+ function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
+ /* istanbul ignore if */
+ if (!hasWarned) {
+ hasWarned = true;
+ // @ts-ignore `console.info` cannot be null error
+ console[console.info ? 'info' : 'log'](` is an experimental feature and its API will likely change.`);
+ }
+ const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
+ const timeout = toNumber(vnode.props && vnode.props.timeout);
+ const suspense = {
+ vnode,
+ parent,
+ parentComponent,
+ isSVG,
+ container,
+ hiddenContainer,
+ anchor,
+ deps: 0,
+ pendingId: 0,
+ timeout: typeof timeout === 'number' ? timeout : -1,
+ activeBranch: null,
+ pendingBranch: null,
+ isInFallback: true,
+ isHydrating,
+ isUnmounted: false,
+ effects: [],
+ resolve(resume = false) {
+ {
+ if (!resume && !suspense.pendingBranch) {
+ throw new Error(`suspense.resolve() is called without a pending branch.`);
+ }
+ if (suspense.isUnmounted) {
+ throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
+ }
+ }
+ const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
+ if (suspense.isHydrating) {
+ suspense.isHydrating = false;
+ }
+ else if (!resume) {
+ const delayEnter = activeBranch &&
+ pendingBranch.transition &&
+ pendingBranch.transition.mode === 'out-in';
+ if (delayEnter) {
+ activeBranch.transition.afterLeave = () => {
+ if (pendingId === suspense.pendingId) {
+ move(pendingBranch, container, anchor, 0 /* ENTER */);
+ }
+ };
+ }
+ // this is initial anchor on mount
+ let { anchor } = suspense;
+ // unmount current active tree
+ if (activeBranch) {
+ // if the fallback tree was mounted, it may have been moved
+ // as part of a parent suspense. get the latest anchor for insertion
+ anchor = next(activeBranch);
+ unmount(activeBranch, parentComponent, suspense, true);
+ }
+ if (!delayEnter) {
+ // move content from off-dom container to actual container
+ move(pendingBranch, container, anchor, 0 /* ENTER */);
+ }
+ }
+ setActiveBranch(suspense, pendingBranch);
+ suspense.pendingBranch = null;
+ suspense.isInFallback = false;
+ // flush buffered effects
+ // check if there is a pending parent suspense
+ let parent = suspense.parent;
+ let hasUnresolvedAncestor = false;
+ while (parent) {
+ if (parent.pendingBranch) {
+ // found a pending parent suspense, merge buffered post jobs
+ // into that parent
+ parent.effects.push(...effects);
+ hasUnresolvedAncestor = true;
+ break;
+ }
+ parent = parent.parent;
+ }
+ // no pending parent suspense, flush all jobs
+ if (!hasUnresolvedAncestor) {
+ queuePostFlushCb(effects);
+ }
+ suspense.effects = [];
+ // invoke @resolve event
+ triggerEvent(vnode, 'onResolve');
+ },
+ fallback(fallbackVNode) {
+ if (!suspense.pendingBranch) {
+ return;
+ }
+ const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
+ // invoke @fallback event
+ triggerEvent(vnode, 'onFallback');
+ const anchor = next(activeBranch);
+ const mountFallback = () => {
+ if (!suspense.isInFallback) {
+ return;
+ }
+ // mount the fallback tree
+ patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
+ isSVG, slotScopeIds, optimized);
+ setActiveBranch(suspense, fallbackVNode);
+ };
+ const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
+ if (delayEnter) {
+ activeBranch.transition.afterLeave = mountFallback;
+ }
+ suspense.isInFallback = true;
+ // unmount current active branch
+ unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
+ true // shouldRemove
+ );
+ if (!delayEnter) {
+ mountFallback();
+ }
+ },
+ move(container, anchor, type) {
+ suspense.activeBranch &&
+ move(suspense.activeBranch, container, anchor, type);
+ suspense.container = container;
+ },
+ next() {
+ return suspense.activeBranch && next(suspense.activeBranch);
+ },
+ registerDep(instance, setupRenderEffect) {
+ const isInPendingSuspense = !!suspense.pendingBranch;
+ if (isInPendingSuspense) {
+ suspense.deps++;
+ }
+ const hydratedEl = instance.vnode.el;
+ instance
+ .asyncDep.catch(err => {
+ handleError(err, instance, 0 /* SETUP_FUNCTION */);
+ })
+ .then(asyncSetupResult => {
+ // retry when the setup() promise resolves.
+ // component may have been unmounted before resolve.
+ if (instance.isUnmounted ||
+ suspense.isUnmounted ||
+ suspense.pendingId !== instance.suspenseId) {
+ return;
+ }
+ // retry from this component
+ instance.asyncResolved = true;
+ const { vnode } = instance;
+ {
+ pushWarningContext(vnode);
+ }
+ handleSetupResult(instance, asyncSetupResult, false);
+ if (hydratedEl) {
+ // vnode may have been replaced if an update happened before the
+ // async dep is resolved.
+ vnode.el = hydratedEl;
+ }
+ const placeholder = !hydratedEl && instance.subTree.el;
+ setupRenderEffect(instance, vnode,
+ // component may have been moved before resolve.
+ // if this is not a hydration, instance.subTree will be the comment
+ // placeholder.
+ parentNode(hydratedEl || instance.subTree.el),
+ // anchor will not be used if this is hydration, so only need to
+ // consider the comment placeholder case.
+ hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
+ if (placeholder) {
+ remove(placeholder);
+ }
+ updateHOCHostEl(instance, vnode.el);
+ {
+ popWarningContext();
+ }
+ // only decrease deps count if suspense is not already resolved
+ if (isInPendingSuspense && --suspense.deps === 0) {
+ suspense.resolve();
+ }
+ });
+ },
+ unmount(parentSuspense, doRemove) {
+ suspense.isUnmounted = true;
+ if (suspense.activeBranch) {
+ unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
+ }
+ if (suspense.pendingBranch) {
+ unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
+ }
+ }
+ };
+ return suspense;
+ }
+ function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
+ /* eslint-disable no-restricted-globals */
+ const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
+ // there are two possible scenarios for server-rendered suspense:
+ // - success: ssr content should be fully resolved
+ // - failure: ssr content should be the fallback branch.
+ // however, on the client we don't really know if it has failed or not
+ // attempt to hydrate the DOM assuming it has succeeded, but we still
+ // need to construct a suspense boundary first
+ const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
+ if (suspense.deps === 0) {
+ suspense.resolve();
+ }
+ return result;
+ /* eslint-enable no-restricted-globals */
+ }
+ function normalizeSuspenseChildren(vnode) {
+ const { shapeFlag, children } = vnode;
+ const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */;
+ vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
+ vnode.ssFallback = isSlotChildren
+ ? normalizeSuspenseSlot(children.fallback)
+ : createVNode(Comment);
+ }
+ function normalizeSuspenseSlot(s) {
+ let block;
+ if (isFunction(s)) {
+ const isCompiledSlot = s._c;
+ if (isCompiledSlot) {
+ // disableTracking: false
+ // allow block tracking for compiled slots
+ // (see ./componentRenderContext.ts)
+ s._d = false;
+ openBlock();
+ }
+ s = s();
+ if (isCompiledSlot) {
+ s._d = true;
+ block = currentBlock;
+ closeBlock();
+ }
+ }
+ if (isArray(s)) {
+ const singleChild = filterSingleRoot(s);
+ if (!singleChild) {
+ warn$1(` slots expect a single root node.`);
+ }
+ s = singleChild;
+ }
+ s = normalizeVNode(s);
+ if (block && !s.dynamicChildren) {
+ s.dynamicChildren = block.filter(c => c !== s);
+ }
+ return s;
+ }
+ function queueEffectWithSuspense(fn, suspense) {
+ if (suspense && suspense.pendingBranch) {
+ if (isArray(fn)) {
+ suspense.effects.push(...fn);
+ }
+ else {
+ suspense.effects.push(fn);
+ }
+ }
+ else {
+ queuePostFlushCb(fn);
+ }
+ }
+ function setActiveBranch(suspense, branch) {
+ suspense.activeBranch = branch;
+ const { vnode, parentComponent } = suspense;
+ const el = (vnode.el = branch.el);
+ // in case suspense is the root node of a component,
+ // recursively update the HOC el
+ if (parentComponent && parentComponent.subTree === vnode) {
+ parentComponent.vnode.el = el;
+ updateHOCHostEl(parentComponent, el);
+ }
+ }
+
+ function provide(key, value) {
+ if (!currentInstance) {
+ {
+ warn$1(`provide() can only be used inside setup().`);
+ }
+ }
+ else {
+ let provides = currentInstance.provides;
+ // by default an instance inherits its parent's provides object
+ // but when it needs to provide values of its own, it creates its
+ // own provides object using parent provides object as prototype.
+ // this way in `inject` we can simply look up injections from direct
+ // parent and let the prototype chain do the work.
+ const parentProvides = currentInstance.parent && currentInstance.parent.provides;
+ if (parentProvides === provides) {
+ provides = currentInstance.provides = Object.create(parentProvides);
+ }
+ // TS doesn't allow symbol as index type
+ provides[key] = value;
+ }
+ }
+ function inject(key, defaultValue, treatDefaultAsFactory = false) {
+ // fallback to `currentRenderingInstance` so that this can be called in
+ // a functional component
+ const instance = currentInstance || currentRenderingInstance;
+ if (instance) {
+ // #2400
+ // to support `app.use` plugins,
+ // fallback to appContext's `provides` if the intance is at root
+ const provides = instance.parent == null
+ ? instance.vnode.appContext && instance.vnode.appContext.provides
+ : instance.parent.provides;
+ if (provides && key in provides) {
+ // TS doesn't allow symbol as index type
+ return provides[key];
+ }
+ else if (arguments.length > 1) {
+ return treatDefaultAsFactory && isFunction(defaultValue)
+ ? defaultValue.call(instance.proxy)
+ : defaultValue;
+ }
+ else {
+ warn$1(`injection "${String(key)}" not found.`);
+ }
+ }
+ else {
+ warn$1(`inject() can only be used inside setup() or functional components.`);
+ }
+ }
+
+ function useTransitionState() {
+ const state = {
+ isMounted: false,
+ isLeaving: false,
+ isUnmounting: false,
+ leavingVNodes: new Map()
+ };
+ onMounted(() => {
+ state.isMounted = true;
+ });
+ onBeforeUnmount(() => {
+ state.isUnmounting = true;
+ });
+ return state;
+ }
+ const TransitionHookValidator = [Function, Array];
+ const BaseTransitionImpl = {
+ name: `BaseTransition`,
+ props: {
+ mode: String,
+ appear: Boolean,
+ persisted: Boolean,
+ // enter
+ onBeforeEnter: TransitionHookValidator,
+ onEnter: TransitionHookValidator,
+ onAfterEnter: TransitionHookValidator,
+ onEnterCancelled: TransitionHookValidator,
+ // leave
+ onBeforeLeave: TransitionHookValidator,
+ onLeave: TransitionHookValidator,
+ onAfterLeave: TransitionHookValidator,
+ onLeaveCancelled: TransitionHookValidator,
+ // appear
+ onBeforeAppear: TransitionHookValidator,
+ onAppear: TransitionHookValidator,
+ onAfterAppear: TransitionHookValidator,
+ onAppearCancelled: TransitionHookValidator
+ },
+ setup(props, { slots }) {
+ const instance = getCurrentInstance();
+ const state = useTransitionState();
+ let prevTransitionKey;
+ return () => {
+ const children = slots.default && getTransitionRawChildren(slots.default(), true);
+ if (!children || !children.length) {
+ return;
+ }
+ // warn multiple elements
+ if (children.length > 1) {
+ warn$1(' can only be used on a single element or component. Use ' +
+ ' for lists.');
+ }
+ // there's no need to track reactivity for these props so use the raw
+ // props for a bit better perf
+ const rawProps = toRaw(props);
+ const { mode } = rawProps;
+ // check mode
+ if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
+ warn$1(`invalid mode: ${mode}`);
+ }
+ // at this point children has a guaranteed length of 1.
+ const child = children[0];
+ if (state.isLeaving) {
+ return emptyPlaceholder(child);
+ }
+ // in the case of , we need to
+ // compare the type of the kept-alive children.
+ const innerChild = getKeepAliveChild(child);
+ if (!innerChild) {
+ return emptyPlaceholder(child);
+ }
+ const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
+ setTransitionHooks(innerChild, enterHooks);
+ const oldChild = instance.subTree;
+ const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
+ let transitionKeyChanged = false;
+ const { getTransitionKey } = innerChild.type;
+ if (getTransitionKey) {
+ const key = getTransitionKey();
+ if (prevTransitionKey === undefined) {
+ prevTransitionKey = key;
+ }
+ else if (key !== prevTransitionKey) {
+ prevTransitionKey = key;
+ transitionKeyChanged = true;
+ }
+ }
+ // handle mode
+ if (oldInnerChild &&
+ oldInnerChild.type !== Comment &&
+ (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
+ const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
+ // update old tree's hooks in case of dynamic transition
+ setTransitionHooks(oldInnerChild, leavingHooks);
+ // switching between different views
+ if (mode === 'out-in') {
+ state.isLeaving = true;
+ // return placeholder node and queue update when leave finishes
+ leavingHooks.afterLeave = () => {
+ state.isLeaving = false;
+ instance.update();
+ };
+ return emptyPlaceholder(child);
+ }
+ else if (mode === 'in-out' && innerChild.type !== Comment) {
+ leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
+ const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
+ leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
+ // early removal callback
+ el._leaveCb = () => {
+ earlyRemove();
+ el._leaveCb = undefined;
+ delete enterHooks.delayedLeave;
+ };
+ enterHooks.delayedLeave = delayedLeave;
+ };
+ }
+ }
+ return child;
+ };
+ }
+ };
+ // export the public type for h/tsx inference
+ // also to avoid inline import() in generated d.ts files
+ const BaseTransition = BaseTransitionImpl;
+ function getLeavingNodesForType(state, vnode) {
+ const { leavingVNodes } = state;
+ let leavingVNodesCache = leavingVNodes.get(vnode.type);
+ if (!leavingVNodesCache) {
+ leavingVNodesCache = Object.create(null);
+ leavingVNodes.set(vnode.type, leavingVNodesCache);
+ }
+ return leavingVNodesCache;
+ }
+ // The transition hooks are attached to the vnode as vnode.transition
+ // and will be called at appropriate timing in the renderer.
+ function resolveTransitionHooks(vnode, props, state, instance) {
+ const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
+ const key = String(vnode.key);
+ const leavingVNodesCache = getLeavingNodesForType(state, vnode);
+ const callHook = (hook, args) => {
+ hook &&
+ callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
+ };
+ const hooks = {
+ mode,
+ persisted,
+ beforeEnter(el) {
+ let hook = onBeforeEnter;
+ if (!state.isMounted) {
+ if (appear) {
+ hook = onBeforeAppear || onBeforeEnter;
+ }
+ else {
+ return;
+ }
+ }
+ // for same element (v-show)
+ if (el._leaveCb) {
+ el._leaveCb(true /* cancelled */);
+ }
+ // for toggled element with same key (v-if)
+ const leavingVNode = leavingVNodesCache[key];
+ if (leavingVNode &&
+ isSameVNodeType(vnode, leavingVNode) &&
+ leavingVNode.el._leaveCb) {
+ // force early removal (not cancelled)
+ leavingVNode.el._leaveCb();
+ }
+ callHook(hook, [el]);
+ },
+ enter(el) {
+ let hook = onEnter;
+ let afterHook = onAfterEnter;
+ let cancelHook = onEnterCancelled;
+ if (!state.isMounted) {
+ if (appear) {
+ hook = onAppear || onEnter;
+ afterHook = onAfterAppear || onAfterEnter;
+ cancelHook = onAppearCancelled || onEnterCancelled;
+ }
+ else {
+ return;
+ }
+ }
+ let called = false;
+ const done = (el._enterCb = (cancelled) => {
+ if (called)
+ return;
+ called = true;
+ if (cancelled) {
+ callHook(cancelHook, [el]);
+ }
+ else {
+ callHook(afterHook, [el]);
+ }
+ if (hooks.delayedLeave) {
+ hooks.delayedLeave();
+ }
+ el._enterCb = undefined;
+ });
+ if (hook) {
+ hook(el, done);
+ if (hook.length <= 1) {
+ done();
+ }
+ }
+ else {
+ done();
+ }
+ },
+ leave(el, remove) {
+ const key = String(vnode.key);
+ if (el._enterCb) {
+ el._enterCb(true /* cancelled */);
+ }
+ if (state.isUnmounting) {
+ return remove();
+ }
+ callHook(onBeforeLeave, [el]);
+ let called = false;
+ const done = (el._leaveCb = (cancelled) => {
+ if (called)
+ return;
+ called = true;
+ remove();
+ if (cancelled) {
+ callHook(onLeaveCancelled, [el]);
+ }
+ else {
+ callHook(onAfterLeave, [el]);
+ }
+ el._leaveCb = undefined;
+ if (leavingVNodesCache[key] === vnode) {
+ delete leavingVNodesCache[key];
+ }
+ });
+ leavingVNodesCache[key] = vnode;
+ if (onLeave) {
+ onLeave(el, done);
+ if (onLeave.length <= 1) {
+ done();
+ }
+ }
+ else {
+ done();
+ }
+ },
+ clone(vnode) {
+ return resolveTransitionHooks(vnode, props, state, instance);
+ }
+ };
+ return hooks;
+ }
+ // the placeholder really only handles one special case: KeepAlive
+ // in the case of a KeepAlive in a leave phase we need to return a KeepAlive
+ // placeholder with empty content to avoid the KeepAlive instance from being
+ // unmounted.
+ function emptyPlaceholder(vnode) {
+ if (isKeepAlive(vnode)) {
+ vnode = cloneVNode(vnode);
+ vnode.children = null;
+ return vnode;
+ }
+ }
+ function getKeepAliveChild(vnode) {
+ return isKeepAlive(vnode)
+ ? vnode.children
+ ? vnode.children[0]
+ : undefined
+ : vnode;
+ }
+ function setTransitionHooks(vnode, hooks) {
+ if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
+ setTransitionHooks(vnode.component.subTree, hooks);
+ }
+ else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
+ vnode.ssContent.transition = hooks.clone(vnode.ssContent);
+ vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
+ }
+ else {
+ vnode.transition = hooks;
+ }
+ }
+ function getTransitionRawChildren(children, keepComment = false) {
+ let ret = [];
+ let keyedFragmentCount = 0;
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i];
+ // handle fragment children case, e.g. v-for
+ if (child.type === Fragment) {
+ if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
+ keyedFragmentCount++;
+ ret = ret.concat(getTransitionRawChildren(child.children, keepComment));
+ }
+ // comment placeholders should be skipped, e.g. v-if
+ else if (keepComment || child.type !== Comment) {
+ ret.push(child);
+ }
+ }
+ // #1126 if a transition children list contains multiple sub fragments, these
+ // fragments will be merged into a flat children array. Since each v-for
+ // fragment may contain different static bindings inside, we need to de-op
+ // these children to force full diffs to ensure correct behavior.
+ if (keyedFragmentCount > 1) {
+ for (let i = 0; i < ret.length; i++) {
+ ret[i].patchFlag = -2 /* BAIL */;
+ }
+ }
+ return ret;
+ }
+
+ // implementation, close to no-op
+ function defineComponent(options) {
+ return isFunction(options) ? { setup: options, name: options.name } : options;
+ }
+
+ const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
+ function defineAsyncComponent(source) {
+ if (isFunction(source)) {
+ source = { loader: source };
+ }
+ const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
+ suspensible = true, onError: userOnError } = source;
+ let pendingRequest = null;
+ let resolvedComp;
+ let retries = 0;
+ const retry = () => {
+ retries++;
+ pendingRequest = null;
+ return load();
+ };
+ const load = () => {
+ let thisRequest;
+ return (pendingRequest ||
+ (thisRequest = pendingRequest =
+ loader()
+ .catch(err => {
+ err = err instanceof Error ? err : new Error(String(err));
+ if (userOnError) {
+ return new Promise((resolve, reject) => {
+ const userRetry = () => resolve(retry());
+ const userFail = () => reject(err);
+ userOnError(err, userRetry, userFail, retries + 1);
+ });
+ }
+ else {
+ throw err;
+ }
+ })
+ .then((comp) => {
+ if (thisRequest !== pendingRequest && pendingRequest) {
+ return pendingRequest;
+ }
+ if (!comp) {
+ warn$1(`Async component loader resolved to undefined. ` +
+ `If you are using retry(), make sure to return its return value.`);
+ }
+ // interop module default
+ if (comp &&
+ (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
+ comp = comp.default;
+ }
+ if (comp && !isObject(comp) && !isFunction(comp)) {
+ throw new Error(`Invalid async component load result: ${comp}`);
+ }
+ resolvedComp = comp;
+ return comp;
+ })));
+ };
+ return defineComponent({
+ name: 'AsyncComponentWrapper',
+ __asyncLoader: load,
+ get __asyncResolved() {
+ return resolvedComp;
+ },
+ setup() {
+ const instance = currentInstance;
+ // already resolved
+ if (resolvedComp) {
+ return () => createInnerComp(resolvedComp, instance);
+ }
+ const onError = (err) => {
+ pendingRequest = null;
+ handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
+ };
+ // suspense-controlled or SSR.
+ if ((suspensible && instance.suspense) ||
+ (false )) {
+ return load()
+ .then(comp => {
+ return () => createInnerComp(comp, instance);
+ })
+ .catch(err => {
+ onError(err);
+ return () => errorComponent
+ ? createVNode(errorComponent, {
+ error: err
+ })
+ : null;
+ });
+ }
+ const loaded = ref(false);
+ const error = ref();
+ const delayed = ref(!!delay);
+ if (delay) {
+ setTimeout(() => {
+ delayed.value = false;
+ }, delay);
+ }
+ if (timeout != null) {
+ setTimeout(() => {
+ if (!loaded.value && !error.value) {
+ const err = new Error(`Async component timed out after ${timeout}ms.`);
+ onError(err);
+ error.value = err;
+ }
+ }, timeout);
+ }
+ load()
+ .then(() => {
+ loaded.value = true;
+ if (instance.parent && isKeepAlive(instance.parent.vnode)) {
+ // parent is keep-alive, force update so the loaded component's
+ // name is taken into account
+ queueJob(instance.parent.update);
+ }
+ })
+ .catch(err => {
+ onError(err);
+ error.value = err;
+ });
+ return () => {
+ if (loaded.value && resolvedComp) {
+ return createInnerComp(resolvedComp, instance);
+ }
+ else if (error.value && errorComponent) {
+ return createVNode(errorComponent, {
+ error: error.value
+ });
+ }
+ else if (loadingComponent && !delayed.value) {
+ return createVNode(loadingComponent);
+ }
+ };
+ }
+ });
+ }
+ function createInnerComp(comp, { vnode: { ref, props, children } }) {
+ const vnode = createVNode(comp, props, children);
+ // ensure inner component inherits the async wrapper's ref owner
+ vnode.ref = ref;
+ return vnode;
+ }
+
+ const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
+ const KeepAliveImpl = {
+ name: `KeepAlive`,
+ // Marker for special handling inside the renderer. We are not using a ===
+ // check directly on KeepAlive in the renderer, because importing it directly
+ // would prevent it from being tree-shaken.
+ __isKeepAlive: true,
+ props: {
+ include: [String, RegExp, Array],
+ exclude: [String, RegExp, Array],
+ max: [String, Number]
+ },
+ setup(props, { slots }) {
+ const instance = getCurrentInstance();
+ // KeepAlive communicates with the instantiated renderer via the
+ // ctx where the renderer passes in its internals,
+ // and the KeepAlive instance exposes activate/deactivate implementations.
+ // The whole point of this is to avoid importing KeepAlive directly in the
+ // renderer to facilitate tree-shaking.
+ const sharedContext = instance.ctx;
+ // if the internal renderer is not registered, it indicates that this is server-side rendering,
+ // for KeepAlive, we just need to render its children
+ if (!sharedContext.renderer) {
+ return slots.default;
+ }
+ const cache = new Map();
+ const keys = new Set();
+ let current = null;
+ {
+ instance.__v_cache = cache;
+ }
+ const parentSuspense = instance.suspense;
+ const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
+ const storageContainer = createElement('div');
+ sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
+ const instance = vnode.component;
+ move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
+ // in case props have changed
+ patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
+ queuePostRenderEffect(() => {
+ instance.isDeactivated = false;
+ if (instance.a) {
+ invokeArrayFns(instance.a);
+ }
+ const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
+ if (vnodeHook) {
+ invokeVNodeHook(vnodeHook, instance.parent, vnode);
+ }
+ }, parentSuspense);
+ {
+ // Update components tree
+ devtoolsComponentAdded(instance);
+ }
+ };
+ sharedContext.deactivate = (vnode) => {
+ const instance = vnode.component;
+ move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
+ queuePostRenderEffect(() => {
+ if (instance.da) {
+ invokeArrayFns(instance.da);
+ }
+ const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
+ if (vnodeHook) {
+ invokeVNodeHook(vnodeHook, instance.parent, vnode);
+ }
+ instance.isDeactivated = true;
+ }, parentSuspense);
+ {
+ // Update components tree
+ devtoolsComponentAdded(instance);
+ }
+ };
+ function unmount(vnode) {
+ // reset the shapeFlag so it can be properly unmounted
+ resetShapeFlag(vnode);
+ _unmount(vnode, instance, parentSuspense);
+ }
+ function pruneCache(filter) {
+ cache.forEach((vnode, key) => {
+ const name = getComponentName(vnode.type);
+ if (name && (!filter || !filter(name))) {
+ pruneCacheEntry(key);
+ }
+ });
+ }
+ function pruneCacheEntry(key) {
+ const cached = cache.get(key);
+ if (!current || cached.type !== current.type) {
+ unmount(cached);
+ }
+ else if (current) {
+ // current active instance should no longer be kept-alive.
+ // we can't unmount it now but it might be later, so reset its flag now.
+ resetShapeFlag(current);
+ }
+ cache.delete(key);
+ keys.delete(key);
+ }
+ // prune cache on include/exclude prop change
+ watch(() => [props.include, props.exclude], ([include, exclude]) => {
+ include && pruneCache(name => matches(include, name));
+ exclude && pruneCache(name => !matches(exclude, name));
+ },
+ // prune post-render after `current` has been updated
+ { flush: 'post', deep: true });
+ // cache sub tree after render
+ let pendingCacheKey = null;
+ const cacheSubtree = () => {
+ // fix #1621, the pendingCacheKey could be 0
+ if (pendingCacheKey != null) {
+ cache.set(pendingCacheKey, getInnerChild(instance.subTree));
+ }
+ };
+ onMounted(cacheSubtree);
+ onUpdated(cacheSubtree);
+ onBeforeUnmount(() => {
+ cache.forEach(cached => {
+ const { subTree, suspense } = instance;
+ const vnode = getInnerChild(subTree);
+ if (cached.type === vnode.type) {
+ // current instance will be unmounted as part of keep-alive's unmount
+ resetShapeFlag(vnode);
+ // but invoke its deactivated hook here
+ const da = vnode.component.da;
+ da && queuePostRenderEffect(da, suspense);
+ return;
+ }
+ unmount(cached);
+ });
+ });
+ return () => {
+ pendingCacheKey = null;
+ if (!slots.default) {
+ return null;
+ }
+ const children = slots.default();
+ const rawVNode = children[0];
+ if (children.length > 1) {
+ {
+ warn$1(`KeepAlive should contain exactly one component child.`);
+ }
+ current = null;
+ return children;
+ }
+ else if (!isVNode(rawVNode) ||
+ (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
+ !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
+ current = null;
+ return rawVNode;
+ }
+ let vnode = getInnerChild(rawVNode);
+ const comp = vnode.type;
+ // for async components, name check should be based in its loaded
+ // inner component if available
+ const name = getComponentName(isAsyncWrapper(vnode)
+ ? vnode.type.__asyncResolved || {}
+ : comp);
+ const { include, exclude, max } = props;
+ if ((include && (!name || !matches(include, name))) ||
+ (exclude && name && matches(exclude, name))) {
+ current = vnode;
+ return rawVNode;
+ }
+ const key = vnode.key == null ? comp : vnode.key;
+ const cachedVNode = cache.get(key);
+ // clone vnode if it's reused because we are going to mutate it
+ if (vnode.el) {
+ vnode = cloneVNode(vnode);
+ if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
+ rawVNode.ssContent = vnode;
+ }
+ }
+ // #1513 it's possible for the returned vnode to be cloned due to attr
+ // fallthrough or scopeId, so the vnode here may not be the final vnode
+ // that is mounted. Instead of caching it directly, we store the pending
+ // key and cache `instance.subTree` (the normalized vnode) in
+ // beforeMount/beforeUpdate hooks.
+ pendingCacheKey = key;
+ if (cachedVNode) {
+ // copy over mounted state
+ vnode.el = cachedVNode.el;
+ vnode.component = cachedVNode.component;
+ if (vnode.transition) {
+ // recursively update transition hooks on subTree
+ setTransitionHooks(vnode, vnode.transition);
+ }
+ // avoid vnode being mounted as fresh
+ vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
+ // make this key the freshest
+ keys.delete(key);
+ keys.add(key);
+ }
+ else {
+ keys.add(key);
+ // prune oldest entry
+ if (max && keys.size > parseInt(max, 10)) {
+ pruneCacheEntry(keys.values().next().value);
+ }
+ }
+ // avoid vnode being unmounted
+ vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
+ current = vnode;
+ return rawVNode;
+ };
+ }
+ };
+ // export the public type for h/tsx inference
+ // also to avoid inline import() in generated d.ts files
+ const KeepAlive = KeepAliveImpl;
+ function matches(pattern, name) {
+ if (isArray(pattern)) {
+ return pattern.some((p) => matches(p, name));
+ }
+ else if (isString(pattern)) {
+ return pattern.split(',').indexOf(name) > -1;
+ }
+ else if (pattern.test) {
+ return pattern.test(name);
+ }
+ /* istanbul ignore next */
+ return false;
+ }
+ function onActivated(hook, target) {
+ registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
+ }
+ function onDeactivated(hook, target) {
+ registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
+ }
+ function registerKeepAliveHook(hook, type, target = currentInstance) {
+ // cache the deactivate branch check wrapper for injected hooks so the same
+ // hook can be properly deduped by the scheduler. "__wdc" stands for "with
+ // deactivation check".
+ const wrappedHook = hook.__wdc ||
+ (hook.__wdc = () => {
+ // only fire the hook if the target instance is NOT in a deactivated branch.
+ let current = target;
+ while (current) {
+ if (current.isDeactivated) {
+ return;
+ }
+ current = current.parent;
+ }
+ hook();
+ });
+ injectHook(type, wrappedHook, target);
+ // In addition to registering it on the target instance, we walk up the parent
+ // chain and register it on all ancestor instances that are keep-alive roots.
+ // This avoids the need to walk the entire component tree when invoking these
+ // hooks, and more importantly, avoids the need to track child components in
+ // arrays.
+ if (target) {
+ let current = target.parent;
+ while (current && current.parent) {
+ if (isKeepAlive(current.parent.vnode)) {
+ injectToKeepAliveRoot(wrappedHook, type, target, current);
+ }
+ current = current.parent;
+ }
+ }
+ }
+ function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
+ // injectHook wraps the original for error handling, so make sure to remove
+ // the wrapped version.
+ const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
+ onUnmounted(() => {
+ remove(keepAliveRoot[type], injected);
+ }, target);
+ }
+ function resetShapeFlag(vnode) {
+ let shapeFlag = vnode.shapeFlag;
+ if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
+ shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
+ }
+ if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
+ shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
+ }
+ vnode.shapeFlag = shapeFlag;
+ }
+ function getInnerChild(vnode) {
+ return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
+ }
+
+ function injectHook(type, hook, target = currentInstance, prepend = false) {
+ if (target) {
+ const hooks = target[type] || (target[type] = []);
+ // cache the error handling wrapper for injected hooks so the same hook
+ // can be properly deduped by the scheduler. "__weh" stands for "with error
+ // handling".
+ const wrappedHook = hook.__weh ||
+ (hook.__weh = (...args) => {
+ if (target.isUnmounted) {
+ return;
+ }
+ // disable tracking inside all lifecycle hooks
+ // since they can potentially be called inside effects.
+ pauseTracking();
+ // Set currentInstance during hook invocation.
+ // This assumes the hook does not synchronously trigger other hooks, which
+ // can only be false when the user does something really funky.
+ setCurrentInstance(target);
+ const res = callWithAsyncErrorHandling(hook, target, type, args);
+ unsetCurrentInstance();
+ resetTracking();
+ return res;
+ });
+ if (prepend) {
+ hooks.unshift(wrappedHook);
+ }
+ else {
+ hooks.push(wrappedHook);
+ }
+ return wrappedHook;
+ }
+ else {
+ const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
+ warn$1(`${apiName} is called when there is no active component instance to be ` +
+ `associated with. ` +
+ `Lifecycle injection APIs can only be used during execution of setup().` +
+ (` If you are using async setup(), make sure to register lifecycle ` +
+ `hooks before the first await statement.`
+ ));
+ }
+ }
+ const createHook = (lifecycle) => (hook, target = currentInstance) =>
+ // post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
+ (!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) &&
+ injectHook(lifecycle, hook, target);
+ const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
+ const onMounted = createHook("m" /* MOUNTED */);
+ const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
+ const onUpdated = createHook("u" /* UPDATED */);
+ const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
+ const onUnmounted = createHook("um" /* UNMOUNTED */);
+ const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */);
+ const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
+ const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
+ function onErrorCaptured(hook, target = currentInstance) {
+ injectHook("ec" /* ERROR_CAPTURED */, hook, target);
+ }
+
+ function createDuplicateChecker() {
+ const cache = Object.create(null);
+ return (type, key) => {
+ if (cache[key]) {
+ warn$1(`${type} property "${key}" is already defined in ${cache[key]}.`);
+ }
+ else {
+ cache[key] = type;
+ }
+ };
+ }
+ let shouldCacheAccess = true;
+ function applyOptions(instance) {
+ const options = resolveMergedOptions(instance);
+ const publicThis = instance.proxy;
+ const ctx = instance.ctx;
+ // do not cache property access on public proxy during state initialization
+ shouldCacheAccess = false;
+ // call beforeCreate first before accessing other options since
+ // the hook may mutate resolved options (#2791)
+ if (options.beforeCreate) {
+ callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */);
+ }
+ const {
+ // state
+ data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
+ // lifecycle
+ created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
+ // public API
+ expose, inheritAttrs,
+ // assets
+ components, directives, filters } = options;
+ const checkDuplicateProperties = createDuplicateChecker() ;
+ {
+ const [propsOptions] = instance.propsOptions;
+ if (propsOptions) {
+ for (const key in propsOptions) {
+ checkDuplicateProperties("Props" /* PROPS */, key);
+ }
+ }
+ }
+ // options initialization order (to be consistent with Vue 2):
+ // - props (already done outside of this function)
+ // - inject
+ // - methods
+ // - data (deferred since it relies on `this` access)
+ // - computed
+ // - watch (deferred since it relies on `this` access)
+ if (injectOptions) {
+ resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
+ }
+ if (methods) {
+ for (const key in methods) {
+ const methodHandler = methods[key];
+ if (isFunction(methodHandler)) {
+ // In dev mode, we use the `createRenderContext` function to define
+ // methods to the proxy target, and those are read-only but
+ // reconfigurable, so it needs to be redefined here
+ {
+ Object.defineProperty(ctx, key, {
+ value: methodHandler.bind(publicThis),
+ configurable: true,
+ enumerable: true,
+ writable: true
+ });
+ }
+ {
+ checkDuplicateProperties("Methods" /* METHODS */, key);
+ }
+ }
+ else {
+ warn$1(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
+ `Did you reference the function correctly?`);
+ }
+ }
+ }
+ if (dataOptions) {
+ if (!isFunction(dataOptions)) {
+ warn$1(`The data option must be a function. ` +
+ `Plain object usage is no longer supported.`);
+ }
+ const data = dataOptions.call(publicThis, publicThis);
+ if (isPromise(data)) {
+ warn$1(`data() returned a Promise - note data() cannot be async; If you ` +
+ `intend to perform data fetching before component renders, use ` +
+ `async setup() + .`);
+ }
+ if (!isObject(data)) {
+ warn$1(`data() should return an object.`);
+ }
+ else {
+ instance.data = reactive(data);
+ {
+ for (const key in data) {
+ checkDuplicateProperties("Data" /* DATA */, key);
+ // expose data on ctx during dev
+ if (key[0] !== '$' && key[0] !== '_') {
+ Object.defineProperty(ctx, key, {
+ configurable: true,
+ enumerable: true,
+ get: () => data[key],
+ set: NOOP
+ });
+ }
+ }
+ }
+ }
+ }
+ // state initialization complete at this point - start caching access
+ shouldCacheAccess = true;
+ if (computedOptions) {
+ for (const key in computedOptions) {
+ const opt = computedOptions[key];
+ const get = isFunction(opt)
+ ? opt.bind(publicThis, publicThis)
+ : isFunction(opt.get)
+ ? opt.get.bind(publicThis, publicThis)
+ : NOOP;
+ if (get === NOOP) {
+ warn$1(`Computed property "${key}" has no getter.`);
+ }
+ const set = !isFunction(opt) && isFunction(opt.set)
+ ? opt.set.bind(publicThis)
+ : () => {
+ warn$1(`Write operation failed: computed property "${key}" is readonly.`);
+ }
+ ;
+ const c = computed({
+ get,
+ set
+ });
+ Object.defineProperty(ctx, key, {
+ enumerable: true,
+ configurable: true,
+ get: () => c.value,
+ set: v => (c.value = v)
+ });
+ {
+ checkDuplicateProperties("Computed" /* COMPUTED */, key);
+ }
+ }
+ }
+ if (watchOptions) {
+ for (const key in watchOptions) {
+ createWatcher(watchOptions[key], ctx, publicThis, key);
+ }
+ }
+ if (provideOptions) {
+ const provides = isFunction(provideOptions)
+ ? provideOptions.call(publicThis)
+ : provideOptions;
+ Reflect.ownKeys(provides).forEach(key => {
+ provide(key, provides[key]);
+ });
+ }
+ if (created) {
+ callHook(created, instance, "c" /* CREATED */);
+ }
+ function registerLifecycleHook(register, hook) {
+ if (isArray(hook)) {
+ hook.forEach(_hook => register(_hook.bind(publicThis)));
+ }
+ else if (hook) {
+ register(hook.bind(publicThis));
+ }
+ }
+ registerLifecycleHook(onBeforeMount, beforeMount);
+ registerLifecycleHook(onMounted, mounted);
+ registerLifecycleHook(onBeforeUpdate, beforeUpdate);
+ registerLifecycleHook(onUpdated, updated);
+ registerLifecycleHook(onActivated, activated);
+ registerLifecycleHook(onDeactivated, deactivated);
+ registerLifecycleHook(onErrorCaptured, errorCaptured);
+ registerLifecycleHook(onRenderTracked, renderTracked);
+ registerLifecycleHook(onRenderTriggered, renderTriggered);
+ registerLifecycleHook(onBeforeUnmount, beforeUnmount);
+ registerLifecycleHook(onUnmounted, unmounted);
+ registerLifecycleHook(onServerPrefetch, serverPrefetch);
+ if (isArray(expose)) {
+ if (expose.length) {
+ const exposed = instance.exposed || (instance.exposed = {});
+ expose.forEach(key => {
+ Object.defineProperty(exposed, key, {
+ get: () => publicThis[key],
+ set: val => (publicThis[key] = val)
+ });
+ });
+ }
+ else if (!instance.exposed) {
+ instance.exposed = {};
+ }
+ }
+ // options that are handled when creating the instance but also need to be
+ // applied from mixins
+ if (render && instance.render === NOOP) {
+ instance.render = render;
+ }
+ if (inheritAttrs != null) {
+ instance.inheritAttrs = inheritAttrs;
+ }
+ // asset options.
+ if (components)
+ instance.components = components;
+ if (directives)
+ instance.directives = directives;
+ }
+ function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) {
+ if (isArray(injectOptions)) {
+ injectOptions = normalizeInject(injectOptions);
+ }
+ for (const key in injectOptions) {
+ const opt = injectOptions[key];
+ let injected;
+ if (isObject(opt)) {
+ if ('default' in opt) {
+ injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
+ }
+ else {
+ injected = inject(opt.from || key);
+ }
+ }
+ else {
+ injected = inject(opt);
+ }
+ if (isRef(injected)) {
+ // TODO remove the check in 3.3
+ if (unwrapRef) {
+ Object.defineProperty(ctx, key, {
+ enumerable: true,
+ configurable: true,
+ get: () => injected.value,
+ set: v => (injected.value = v)
+ });
+ }
+ else {
+ {
+ warn$1(`injected property "${key}" is a ref and will be auto-unwrapped ` +
+ `and no longer needs \`.value\` in the next minor release. ` +
+ `To opt-in to the new behavior now, ` +
+ `set \`app.config.unwrapInjectedRef = true\` (this config is ` +
+ `temporary and will not be needed in the future.)`);
+ }
+ ctx[key] = injected;
+ }
+ }
+ else {
+ ctx[key] = injected;
+ }
+ {
+ checkDuplicateProperties("Inject" /* INJECT */, key);
+ }
+ }
+ }
+ function callHook(hook, instance, type) {
+ callWithAsyncErrorHandling(isArray(hook)
+ ? hook.map(h => h.bind(instance.proxy))
+ : hook.bind(instance.proxy), instance, type);
+ }
+ function createWatcher(raw, ctx, publicThis, key) {
+ const getter = key.includes('.')
+ ? createPathGetter(publicThis, key)
+ : () => publicThis[key];
+ if (isString(raw)) {
+ const handler = ctx[raw];
+ if (isFunction(handler)) {
+ watch(getter, handler);
+ }
+ else {
+ warn$1(`Invalid watch handler specified by key "${raw}"`, handler);
+ }
+ }
+ else if (isFunction(raw)) {
+ watch(getter, raw.bind(publicThis));
+ }
+ else if (isObject(raw)) {
+ if (isArray(raw)) {
+ raw.forEach(r => createWatcher(r, ctx, publicThis, key));
+ }
+ else {
+ const handler = isFunction(raw.handler)
+ ? raw.handler.bind(publicThis)
+ : ctx[raw.handler];
+ if (isFunction(handler)) {
+ watch(getter, handler, raw);
+ }
+ else {
+ warn$1(`Invalid watch handler specified by key "${raw.handler}"`, handler);
+ }
+ }
+ }
+ else {
+ warn$1(`Invalid watch option: "${key}"`, raw);
+ }
+ }
+ /**
+ * Resolve merged options and cache it on the component.
+ * This is done only once per-component since the merging does not involve
+ * instances.
+ */
+ function resolveMergedOptions(instance) {
+ const base = instance.type;
+ const { mixins, extends: extendsOptions } = base;
+ const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
+ const cached = cache.get(base);
+ let resolved;
+ if (cached) {
+ resolved = cached;
+ }
+ else if (!globalMixins.length && !mixins && !extendsOptions) {
+ {
+ resolved = base;
+ }
+ }
+ else {
+ resolved = {};
+ if (globalMixins.length) {
+ globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
+ }
+ mergeOptions(resolved, base, optionMergeStrategies);
+ }
+ cache.set(base, resolved);
+ return resolved;
+ }
+ function mergeOptions(to, from, strats, asMixin = false) {
+ const { mixins, extends: extendsOptions } = from;
+ if (extendsOptions) {
+ mergeOptions(to, extendsOptions, strats, true);
+ }
+ if (mixins) {
+ mixins.forEach((m) => mergeOptions(to, m, strats, true));
+ }
+ for (const key in from) {
+ if (asMixin && key === 'expose') {
+ warn$1(`"expose" option is ignored when declared in mixins or extends. ` +
+ `It should only be declared in the base component itself.`);
+ }
+ else {
+ const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
+ to[key] = strat ? strat(to[key], from[key]) : from[key];
+ }
+ }
+ return to;
+ }
+ const internalOptionMergeStrats = {
+ data: mergeDataFn,
+ props: mergeObjectOptions,
+ emits: mergeObjectOptions,
+ // objects
+ methods: mergeObjectOptions,
+ computed: mergeObjectOptions,
+ // lifecycle
+ beforeCreate: mergeAsArray,
+ created: mergeAsArray,
+ beforeMount: mergeAsArray,
+ mounted: mergeAsArray,
+ beforeUpdate: mergeAsArray,
+ updated: mergeAsArray,
+ beforeDestroy: mergeAsArray,
+ beforeUnmount: mergeAsArray,
+ destroyed: mergeAsArray,
+ unmounted: mergeAsArray,
+ activated: mergeAsArray,
+ deactivated: mergeAsArray,
+ errorCaptured: mergeAsArray,
+ serverPrefetch: mergeAsArray,
+ // assets
+ components: mergeObjectOptions,
+ directives: mergeObjectOptions,
+ // watch
+ watch: mergeWatchOptions,
+ // provide / inject
+ provide: mergeDataFn,
+ inject: mergeInject
+ };
+ function mergeDataFn(to, from) {
+ if (!from) {
+ return to;
+ }
+ if (!to) {
+ return from;
+ }
+ return function mergedDataFn() {
+ return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
+ };
+ }
+ function mergeInject(to, from) {
+ return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
+ }
+ function normalizeInject(raw) {
+ if (isArray(raw)) {
+ const res = {};
+ for (let i = 0; i < raw.length; i++) {
+ res[raw[i]] = raw[i];
+ }
+ return res;
+ }
+ return raw;
+ }
+ function mergeAsArray(to, from) {
+ return to ? [...new Set([].concat(to, from))] : from;
+ }
+ function mergeObjectOptions(to, from) {
+ return to ? extend(extend(Object.create(null), to), from) : from;
+ }
+ function mergeWatchOptions(to, from) {
+ if (!to)
+ return from;
+ if (!from)
+ return to;
+ const merged = extend(Object.create(null), to);
+ for (const key in from) {
+ merged[key] = mergeAsArray(to[key], from[key]);
+ }
+ return merged;
+ }
+
+ function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
+ isSSR = false) {
+ const props = {};
+ const attrs = {};
+ def(attrs, InternalObjectKey, 1);
+ instance.propsDefaults = Object.create(null);
+ setFullProps(instance, rawProps, props, attrs);
+ // ensure all declared prop keys are present
+ for (const key in instance.propsOptions[0]) {
+ if (!(key in props)) {
+ props[key] = undefined;
+ }
+ }
+ // validation
+ {
+ validateProps(rawProps || {}, props, instance);
+ }
+ if (isStateful) {
+ // stateful
+ instance.props = isSSR ? props : shallowReactive(props);
+ }
+ else {
+ if (!instance.type.props) {
+ // functional w/ optional props, props === attrs
+ instance.props = attrs;
+ }
+ else {
+ // functional w/ declared props
+ instance.props = props;
+ }
+ }
+ instance.attrs = attrs;
+ }
+ function updateProps(instance, rawProps, rawPrevProps, optimized) {
+ const { props, attrs, vnode: { patchFlag } } = instance;
+ const rawCurrentProps = toRaw(props);
+ const [options] = instance.propsOptions;
+ let hasAttrsChanged = false;
+ if (
+ // always force full diff in dev
+ // - #1942 if hmr is enabled with sfc component
+ // - vite#872 non-sfc component used by sfc component
+ !((instance.type.__hmrId ||
+ (instance.parent && instance.parent.type.__hmrId))) &&
+ (optimized || patchFlag > 0) &&
+ !(patchFlag & 16 /* FULL_PROPS */)) {
+ if (patchFlag & 8 /* PROPS */) {
+ // Compiler-generated props & no keys change, just set the updated
+ // the props.
+ const propsToUpdate = instance.vnode.dynamicProps;
+ for (let i = 0; i < propsToUpdate.length; i++) {
+ let key = propsToUpdate[i];
+ // PROPS flag guarantees rawProps to be non-null
+ const value = rawProps[key];
+ if (options) {
+ // attr / props separation was done on init and will be consistent
+ // in this code path, so just check if attrs have it.
+ if (hasOwn(attrs, key)) {
+ if (value !== attrs[key]) {
+ attrs[key] = value;
+ hasAttrsChanged = true;
+ }
+ }
+ else {
+ const camelizedKey = camelize(key);
+ props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
+ }
+ }
+ else {
+ if (value !== attrs[key]) {
+ attrs[key] = value;
+ hasAttrsChanged = true;
+ }
+ }
+ }
+ }
+ }
+ else {
+ // full props update.
+ if (setFullProps(instance, rawProps, props, attrs)) {
+ hasAttrsChanged = true;
+ }
+ // in case of dynamic props, check if we need to delete keys from
+ // the props object
+ let kebabKey;
+ for (const key in rawCurrentProps) {
+ if (!rawProps ||
+ // for camelCase
+ (!hasOwn(rawProps, key) &&
+ // it's possible the original props was passed in as kebab-case
+ // and converted to camelCase (#955)
+ ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
+ if (options) {
+ if (rawPrevProps &&
+ // for camelCase
+ (rawPrevProps[key] !== undefined ||
+ // for kebab-case
+ rawPrevProps[kebabKey] !== undefined)) {
+ props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
+ }
+ }
+ else {
+ delete props[key];
+ }
+ }
+ }
+ // in the case of functional component w/o props declaration, props and
+ // attrs point to the same object so it should already have been updated.
+ if (attrs !== rawCurrentProps) {
+ for (const key in attrs) {
+ if (!rawProps || !hasOwn(rawProps, key)) {
+ delete attrs[key];
+ hasAttrsChanged = true;
+ }
+ }
+ }
+ }
+ // trigger updates for $attrs in case it's used in component slots
+ if (hasAttrsChanged) {
+ trigger(instance, "set" /* SET */, '$attrs');
+ }
+ {
+ validateProps(rawProps || {}, props, instance);
+ }
+ }
+ function setFullProps(instance, rawProps, props, attrs) {
+ const [options, needCastKeys] = instance.propsOptions;
+ let hasAttrsChanged = false;
+ let rawCastValues;
+ if (rawProps) {
+ for (let key in rawProps) {
+ // key, ref are reserved and never passed down
+ if (isReservedProp(key)) {
+ continue;
+ }
+ const value = rawProps[key];
+ // prop option names are camelized during normalization, so to support
+ // kebab -> camel conversion here we need to camelize the key.
+ let camelKey;
+ if (options && hasOwn(options, (camelKey = camelize(key)))) {
+ if (!needCastKeys || !needCastKeys.includes(camelKey)) {
+ props[camelKey] = value;
+ }
+ else {
+ (rawCastValues || (rawCastValues = {}))[camelKey] = value;
+ }
+ }
+ else if (!isEmitListener(instance.emitsOptions, key)) {
+ if (value !== attrs[key]) {
+ attrs[key] = value;
+ hasAttrsChanged = true;
+ }
+ }
+ }
+ }
+ if (needCastKeys) {
+ const rawCurrentProps = toRaw(props);
+ const castValues = rawCastValues || EMPTY_OBJ;
+ for (let i = 0; i < needCastKeys.length; i++) {
+ const key = needCastKeys[i];
+ props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
+ }
+ }
+ return hasAttrsChanged;
+ }
+ function resolvePropValue(options, props, key, value, instance, isAbsent) {
+ const opt = options[key];
+ if (opt != null) {
+ const hasDefault = hasOwn(opt, 'default');
+ // default values
+ if (hasDefault && value === undefined) {
+ const defaultValue = opt.default;
+ if (opt.type !== Function && isFunction(defaultValue)) {
+ const { propsDefaults } = instance;
+ if (key in propsDefaults) {
+ value = propsDefaults[key];
+ }
+ else {
+ setCurrentInstance(instance);
+ value = propsDefaults[key] = defaultValue.call(null, props);
+ unsetCurrentInstance();
+ }
+ }
+ else {
+ value = defaultValue;
+ }
+ }
+ // boolean casting
+ if (opt[0 /* shouldCast */]) {
+ if (isAbsent && !hasDefault) {
+ value = false;
+ }
+ else if (opt[1 /* shouldCastTrue */] &&
+ (value === '' || value === hyphenate(key))) {
+ value = true;
+ }
+ }
+ }
+ return value;
+ }
+ function normalizePropsOptions(comp, appContext, asMixin = false) {
+ const cache = appContext.propsCache;
+ const cached = cache.get(comp);
+ if (cached) {
+ return cached;
+ }
+ const raw = comp.props;
+ const normalized = {};
+ const needCastKeys = [];
+ // apply mixin/extends props
+ let hasExtends = false;
+ if (!isFunction(comp)) {
+ const extendProps = (raw) => {
+ hasExtends = true;
+ const [props, keys] = normalizePropsOptions(raw, appContext, true);
+ extend(normalized, props);
+ if (keys)
+ needCastKeys.push(...keys);
+ };
+ if (!asMixin && appContext.mixins.length) {
+ appContext.mixins.forEach(extendProps);
+ }
+ if (comp.extends) {
+ extendProps(comp.extends);
+ }
+ if (comp.mixins) {
+ comp.mixins.forEach(extendProps);
+ }
+ }
+ if (!raw && !hasExtends) {
+ cache.set(comp, EMPTY_ARR);
+ return EMPTY_ARR;
+ }
+ if (isArray(raw)) {
+ for (let i = 0; i < raw.length; i++) {
+ if (!isString(raw[i])) {
+ warn$1(`props must be strings when using array syntax.`, raw[i]);
+ }
+ const normalizedKey = camelize(raw[i]);
+ if (validatePropName(normalizedKey)) {
+ normalized[normalizedKey] = EMPTY_OBJ;
+ }
+ }
+ }
+ else if (raw) {
+ if (!isObject(raw)) {
+ warn$1(`invalid props options`, raw);
+ }
+ for (const key in raw) {
+ const normalizedKey = camelize(key);
+ if (validatePropName(normalizedKey)) {
+ const opt = raw[key];
+ const prop = (normalized[normalizedKey] =
+ isArray(opt) || isFunction(opt) ? { type: opt } : opt);
+ if (prop) {
+ const booleanIndex = getTypeIndex(Boolean, prop.type);
+ const stringIndex = getTypeIndex(String, prop.type);
+ prop[0 /* shouldCast */] = booleanIndex > -1;
+ prop[1 /* shouldCastTrue */] =
+ stringIndex < 0 || booleanIndex < stringIndex;
+ // if the prop needs boolean casting or default value
+ if (booleanIndex > -1 || hasOwn(prop, 'default')) {
+ needCastKeys.push(normalizedKey);
+ }
+ }
+ }
+ }
+ }
+ const res = [normalized, needCastKeys];
+ cache.set(comp, res);
+ return res;
+ }
+ function validatePropName(key) {
+ if (key[0] !== '$') {
+ return true;
+ }
+ else {
+ warn$1(`Invalid prop name: "${key}" is a reserved property.`);
+ }
+ return false;
+ }
+ // use function string name to check type constructors
+ // so that it works across vms / iframes.
+ function getType(ctor) {
+ const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
+ return match ? match[1] : ctor === null ? 'null' : '';
+ }
+ function isSameType(a, b) {
+ return getType(a) === getType(b);
+ }
+ function getTypeIndex(type, expectedTypes) {
+ if (isArray(expectedTypes)) {
+ return expectedTypes.findIndex(t => isSameType(t, type));
+ }
+ else if (isFunction(expectedTypes)) {
+ return isSameType(expectedTypes, type) ? 0 : -1;
+ }
+ return -1;
+ }
+ /**
+ * dev only
+ */
+ function validateProps(rawProps, props, instance) {
+ const resolvedValues = toRaw(props);
+ const options = instance.propsOptions[0];
+ for (const key in options) {
+ let opt = options[key];
+ if (opt == null)
+ continue;
+ validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
+ }
+ }
+ /**
+ * dev only
+ */
+ function validateProp(name, value, prop, isAbsent) {
+ const { type, required, validator } = prop;
+ // required!
+ if (required && isAbsent) {
+ warn$1('Missing required prop: "' + name + '"');
+ return;
+ }
+ // missing but optional
+ if (value == null && !prop.required) {
+ return;
+ }
+ // type check
+ if (type != null && type !== true) {
+ let isValid = false;
+ const types = isArray(type) ? type : [type];
+ const expectedTypes = [];
+ // value is valid as long as one of the specified types match
+ for (let i = 0; i < types.length && !isValid; i++) {
+ const { valid, expectedType } = assertType(value, types[i]);
+ expectedTypes.push(expectedType || '');
+ isValid = valid;
+ }
+ if (!isValid) {
+ warn$1(getInvalidTypeMessage(name, value, expectedTypes));
+ return;
+ }
+ }
+ // custom validator
+ if (validator && !validator(value)) {
+ warn$1('Invalid prop: custom validator check failed for prop "' + name + '".');
+ }
+ }
+ const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
+ /**
+ * dev only
+ */
+ function assertType(value, type) {
+ let valid;
+ const expectedType = getType(type);
+ if (isSimpleType(expectedType)) {
+ const t = typeof value;
+ valid = t === expectedType.toLowerCase();
+ // for primitive wrapper objects
+ if (!valid && t === 'object') {
+ valid = value instanceof type;
+ }
+ }
+ else if (expectedType === 'Object') {
+ valid = isObject(value);
+ }
+ else if (expectedType === 'Array') {
+ valid = isArray(value);
+ }
+ else if (expectedType === 'null') {
+ valid = value === null;
+ }
+ else {
+ valid = value instanceof type;
+ }
+ return {
+ valid,
+ expectedType
+ };
+ }
+ /**
+ * dev only
+ */
+ function getInvalidTypeMessage(name, value, expectedTypes) {
+ let message = `Invalid prop: type check failed for prop "${name}".` +
+ ` Expected ${expectedTypes.map(capitalize).join(' | ')}`;
+ const expectedType = expectedTypes[0];
+ const receivedType = toRawType(value);
+ const expectedValue = styleValue(value, expectedType);
+ const receivedValue = styleValue(value, receivedType);
+ // check if we need to specify expected value
+ if (expectedTypes.length === 1 &&
+ isExplicable(expectedType) &&
+ !isBoolean(expectedType, receivedType)) {
+ message += ` with value ${expectedValue}`;
+ }
+ message += `, got ${receivedType} `;
+ // check if we need to specify received value
+ if (isExplicable(receivedType)) {
+ message += `with value ${receivedValue}.`;
+ }
+ return message;
+ }
+ /**
+ * dev only
+ */
+ function styleValue(value, type) {
+ if (type === 'String') {
+ return `"${value}"`;
+ }
+ else if (type === 'Number') {
+ return `${Number(value)}`;
+ }
+ else {
+ return `${value}`;
+ }
+ }
+ /**
+ * dev only
+ */
+ function isExplicable(type) {
+ const explicitTypes = ['string', 'number', 'boolean'];
+ return explicitTypes.some(elem => type.toLowerCase() === elem);
+ }
+ /**
+ * dev only
+ */
+ function isBoolean(...args) {
+ return args.some(elem => elem.toLowerCase() === 'boolean');
+ }
+
+ const isInternalKey = (key) => key[0] === '_' || key === '$stable';
+ const normalizeSlotValue = (value) => isArray(value)
+ ? value.map(normalizeVNode)
+ : [normalizeVNode(value)];
+ const normalizeSlot = (key, rawSlot, ctx) => {
+ const normalized = withCtx((...args) => {
+ if (currentInstance) {
+ warn$1(`Slot "${key}" invoked outside of the render function: ` +
+ `this will not track dependencies used in the slot. ` +
+ `Invoke the slot function inside the render function instead.`);
+ }
+ return normalizeSlotValue(rawSlot(...args));
+ }, ctx);
+ normalized._c = false;
+ return normalized;
+ };
+ const normalizeObjectSlots = (rawSlots, slots, instance) => {
+ const ctx = rawSlots._ctx;
+ for (const key in rawSlots) {
+ if (isInternalKey(key))
+ continue;
+ const value = rawSlots[key];
+ if (isFunction(value)) {
+ slots[key] = normalizeSlot(key, value, ctx);
+ }
+ else if (value != null) {
+ {
+ warn$1(`Non-function value encountered for slot "${key}". ` +
+ `Prefer function slots for better performance.`);
+ }
+ const normalized = normalizeSlotValue(value);
+ slots[key] = () => normalized;
+ }
+ }
+ };
+ const normalizeVNodeSlots = (instance, children) => {
+ if (!isKeepAlive(instance.vnode) &&
+ !(false )) {
+ warn$1(`Non-function value encountered for default slot. ` +
+ `Prefer function slots for better performance.`);
+ }
+ const normalized = normalizeSlotValue(children);
+ instance.slots.default = () => normalized;
+ };
+ const initSlots = (instance, children) => {
+ if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
+ const type = children._;
+ if (type) {
+ // users can get the shallow readonly version of the slots object through `this.$slots`,
+ // we should avoid the proxy object polluting the slots of the internal instance
+ instance.slots = toRaw(children);
+ // make compiler marker non-enumerable
+ def(children, '_', type);
+ }
+ else {
+ normalizeObjectSlots(children, (instance.slots = {}));
+ }
+ }
+ else {
+ instance.slots = {};
+ if (children) {
+ normalizeVNodeSlots(instance, children);
+ }
+ }
+ def(instance.slots, InternalObjectKey, 1);
+ };
+ const updateSlots = (instance, children, optimized) => {
+ const { vnode, slots } = instance;
+ let needDeletionCheck = true;
+ let deletionComparisonTarget = EMPTY_OBJ;
+ if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
+ const type = children._;
+ if (type) {
+ // compiled slots.
+ if (isHmrUpdating) {
+ // Parent was HMR updated so slot content may have changed.
+ // force update slots and mark instance for hmr as well
+ extend(slots, children);
+ }
+ else if (optimized && type === 1 /* STABLE */) {
+ // compiled AND stable.
+ // no need to update, and skip stale slots removal.
+ needDeletionCheck = false;
+ }
+ else {
+ // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
+ // normalization.
+ extend(slots, children);
+ // #2893
+ // when rendering the optimized slots by manually written render function,
+ // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
+ // i.e. let the `renderSlot` create the bailed Fragment
+ if (!optimized && type === 1 /* STABLE */) {
+ delete slots._;
+ }
+ }
+ }
+ else {
+ needDeletionCheck = !children.$stable;
+ normalizeObjectSlots(children, slots);
+ }
+ deletionComparisonTarget = children;
+ }
+ else if (children) {
+ // non slot object children (direct value) passed to a component
+ normalizeVNodeSlots(instance, children);
+ deletionComparisonTarget = { default: 1 };
+ }
+ // delete stale slots
+ if (needDeletionCheck) {
+ for (const key in slots) {
+ if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
+ delete slots[key];
+ }
+ }
+ }
+ };
+
+ /**
+ Runtime helper for applying directives to a vnode. Example usage:
+
+ const comp = resolveComponent('comp')
+ const foo = resolveDirective('foo')
+ const bar = resolveDirective('bar')
+
+ return withDirectives(h(comp), [
+ [foo, this.x],
+ [bar, this.y]
+ ])
+ */
+ const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
+ function validateDirectiveName(name) {
+ if (isBuiltInDirective(name)) {
+ warn$1('Do not use built-in directive ids as custom directive id: ' + name);
+ }
+ }
+ /**
+ * Adds directives to a VNode.
+ */
+ function withDirectives(vnode, directives) {
+ const internalInstance = currentRenderingInstance;
+ if (internalInstance === null) {
+ warn$1(`withDirectives can only be used inside render functions.`);
+ return vnode;
+ }
+ const instance = internalInstance.proxy;
+ const bindings = vnode.dirs || (vnode.dirs = []);
+ for (let i = 0; i < directives.length; i++) {
+ let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
+ if (isFunction(dir)) {
+ dir = {
+ mounted: dir,
+ updated: dir
+ };
+ }
+ if (dir.deep) {
+ traverse(value);
+ }
+ bindings.push({
+ dir,
+ instance,
+ value,
+ oldValue: void 0,
+ arg,
+ modifiers
+ });
+ }
+ return vnode;
+ }
+ function invokeDirectiveHook(vnode, prevVNode, instance, name) {
+ const bindings = vnode.dirs;
+ const oldBindings = prevVNode && prevVNode.dirs;
+ for (let i = 0; i < bindings.length; i++) {
+ const binding = bindings[i];
+ if (oldBindings) {
+ binding.oldValue = oldBindings[i].value;
+ }
+ let hook = binding.dir[name];
+ if (hook) {
+ // disable tracking inside all lifecycle hooks
+ // since they can potentially be called inside effects.
+ pauseTracking();
+ callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
+ vnode.el,
+ binding,
+ vnode,
+ prevVNode
+ ]);
+ resetTracking();
+ }
+ }
+ }
+
+ function createAppContext() {
+ return {
+ app: null,
+ config: {
+ isNativeTag: NO,
+ performance: false,
+ globalProperties: {},
+ optionMergeStrategies: {},
+ errorHandler: undefined,
+ warnHandler: undefined,
+ compilerOptions: {}
+ },
+ mixins: [],
+ components: {},
+ directives: {},
+ provides: Object.create(null),
+ optionsCache: new WeakMap(),
+ propsCache: new WeakMap(),
+ emitsCache: new WeakMap()
+ };
+ }
+ let uid = 0;
+ function createAppAPI(render, hydrate) {
+ return function createApp(rootComponent, rootProps = null) {
+ if (rootProps != null && !isObject(rootProps)) {
+ warn$1(`root props passed to app.mount() must be an object.`);
+ rootProps = null;
+ }
+ const context = createAppContext();
+ const installedPlugins = new Set();
+ let isMounted = false;
+ const app = (context.app = {
+ _uid: uid++,
+ _component: rootComponent,
+ _props: rootProps,
+ _container: null,
+ _context: context,
+ _instance: null,
+ version,
+ get config() {
+ return context.config;
+ },
+ set config(v) {
+ {
+ warn$1(`app.config cannot be replaced. Modify individual options instead.`);
+ }
+ },
+ use(plugin, ...options) {
+ if (installedPlugins.has(plugin)) {
+ warn$1(`Plugin has already been applied to target app.`);
+ }
+ else if (plugin && isFunction(plugin.install)) {
+ installedPlugins.add(plugin);
+ plugin.install(app, ...options);
+ }
+ else if (isFunction(plugin)) {
+ installedPlugins.add(plugin);
+ plugin(app, ...options);
+ }
+ else {
+ warn$1(`A plugin must either be a function or an object with an "install" ` +
+ `function.`);
+ }
+ return app;
+ },
+ mixin(mixin) {
+ {
+ if (!context.mixins.includes(mixin)) {
+ context.mixins.push(mixin);
+ }
+ else {
+ warn$1('Mixin has already been applied to target app' +
+ (mixin.name ? `: ${mixin.name}` : ''));
+ }
+ }
+ return app;
+ },
+ component(name, component) {
+ {
+ validateComponentName(name, context.config);
+ }
+ if (!component) {
+ return context.components[name];
+ }
+ if (context.components[name]) {
+ warn$1(`Component "${name}" has already been registered in target app.`);
+ }
+ context.components[name] = component;
+ return app;
+ },
+ directive(name, directive) {
+ {
+ validateDirectiveName(name);
+ }
+ if (!directive) {
+ return context.directives[name];
+ }
+ if (context.directives[name]) {
+ warn$1(`Directive "${name}" has already been registered in target app.`);
+ }
+ context.directives[name] = directive;
+ return app;
+ },
+ mount(rootContainer, isHydrate, isSVG) {
+ if (!isMounted) {
+ const vnode = createVNode(rootComponent, rootProps);
+ // store app context on the root VNode.
+ // this will be set on the root instance on initial mount.
+ vnode.appContext = context;
+ // HMR root reload
+ {
+ context.reload = () => {
+ render(cloneVNode(vnode), rootContainer, isSVG);
+ };
+ }
+ if (isHydrate && hydrate) {
+ hydrate(vnode, rootContainer);
+ }
+ else {
+ render(vnode, rootContainer, isSVG);
+ }
+ isMounted = true;
+ app._container = rootContainer;
+ rootContainer.__vue_app__ = app;
+ {
+ app._instance = vnode.component;
+ devtoolsInitApp(app, version);
+ }
+ return vnode.component.proxy;
+ }
+ else {
+ warn$1(`App has already been mounted.\n` +
+ `If you want to remount the same app, move your app creation logic ` +
+ `into a factory function and create fresh app instances for each ` +
+ `mount - e.g. \`const createMyApp = () => createApp(App)\``);
+ }
+ },
+ unmount() {
+ if (isMounted) {
+ render(null, app._container);
+ {
+ app._instance = null;
+ devtoolsUnmountApp(app);
+ }
+ delete app._container.__vue_app__;
+ }
+ else {
+ warn$1(`Cannot unmount an app that is not mounted.`);
+ }
+ },
+ provide(key, value) {
+ if (key in context.provides) {
+ warn$1(`App already provides property with key "${String(key)}". ` +
+ `It will be overwritten with the new value.`);
+ }
+ // TypeScript doesn't allow symbols as index type
+ // https://github.com/Microsoft/TypeScript/issues/24587
+ context.provides[key] = value;
+ return app;
+ }
+ });
+ return app;
+ };
+ }
+
+ let hasMismatch = false;
+ const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
+ const isComment = (node) => node.nodeType === 8 /* COMMENT */;
+ // Note: hydration is DOM-specific
+ // But we have to place it in core due to tight coupling with core - splitting
+ // it out creates a ton of unnecessary complexity.
+ // Hydration also depends on some renderer internal logic which needs to be
+ // passed in via arguments.
+ function createHydrationFunctions(rendererInternals) {
+ const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
+ const hydrate = (vnode, container) => {
+ if (!container.hasChildNodes()) {
+ warn$1(`Attempting to hydrate existing markup but container is empty. ` +
+ `Performing full mount instead.`);
+ patch(null, vnode, container);
+ flushPostFlushCbs();
+ return;
+ }
+ hasMismatch = false;
+ hydrateNode(container.firstChild, vnode, null, null, null);
+ flushPostFlushCbs();
+ if (hasMismatch && !false) {
+ // this error should show up in production
+ console.error(`Hydration completed but contains mismatches.`);
+ }
+ };
+ const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
+ const isFragmentStart = isComment(node) && node.data === '[';
+ const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
+ const { type, ref, shapeFlag } = vnode;
+ const domType = node.nodeType;
+ vnode.el = node;
+ let nextNode = null;
+ switch (type) {
+ case Text:
+ if (domType !== 3 /* TEXT */) {
+ nextNode = onMismatch();
+ }
+ else {
+ if (node.data !== vnode.children) {
+ hasMismatch = true;
+ warn$1(`Hydration text mismatch:` +
+ `\n- Client: ${JSON.stringify(node.data)}` +
+ `\n- Server: ${JSON.stringify(vnode.children)}`);
+ node.data = vnode.children;
+ }
+ nextNode = nextSibling(node);
+ }
+ break;
+ case Comment:
+ if (domType !== 8 /* COMMENT */ || isFragmentStart) {
+ nextNode = onMismatch();
+ }
+ else {
+ nextNode = nextSibling(node);
+ }
+ break;
+ case Static:
+ if (domType !== 1 /* ELEMENT */) {
+ nextNode = onMismatch();
+ }
+ else {
+ // determine anchor, adopt content
+ nextNode = node;
+ // if the static vnode has its content stripped during build,
+ // adopt it from the server-rendered HTML.
+ const needToAdoptContent = !vnode.children.length;
+ for (let i = 0; i < vnode.staticCount; i++) {
+ if (needToAdoptContent)
+ vnode.children += nextNode.outerHTML;
+ if (i === vnode.staticCount - 1) {
+ vnode.anchor = nextNode;
+ }
+ nextNode = nextSibling(nextNode);
+ }
+ return nextNode;
+ }
+ break;
+ case Fragment:
+ if (!isFragmentStart) {
+ nextNode = onMismatch();
+ }
+ else {
+ nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
+ }
+ break;
+ default:
+ if (shapeFlag & 1 /* ELEMENT */) {
+ if (domType !== 1 /* ELEMENT */ ||
+ vnode.type.toLowerCase() !==
+ node.tagName.toLowerCase()) {
+ nextNode = onMismatch();
+ }
+ else {
+ nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
+ }
+ }
+ else if (shapeFlag & 6 /* COMPONENT */) {
+ // when setting up the render effect, if the initial vnode already
+ // has .el set, the component will perform hydration instead of mount
+ // on its sub-tree.
+ vnode.slotScopeIds = slotScopeIds;
+ const container = parentNode(node);
+ mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
+ // component may be async, so in the case of fragments we cannot rely
+ // on component's rendered output to determine the end of the fragment
+ // instead, we do a lookahead to find the end anchor node.
+ nextNode = isFragmentStart
+ ? locateClosingAsyncAnchor(node)
+ : nextSibling(node);
+ // #3787
+ // if component is async, it may get moved / unmounted before its
+ // inner component is loaded, so we need to give it a placeholder
+ // vnode that matches its adopted DOM.
+ if (isAsyncWrapper(vnode)) {
+ let subTree;
+ if (isFragmentStart) {
+ subTree = createVNode(Fragment);
+ subTree.anchor = nextNode
+ ? nextNode.previousSibling
+ : container.lastChild;
+ }
+ else {
+ subTree =
+ node.nodeType === 3 ? createTextVNode('') : createVNode('div');
+ }
+ subTree.el = node;
+ vnode.component.subTree = subTree;
+ }
+ }
+ else if (shapeFlag & 64 /* TELEPORT */) {
+ if (domType !== 8 /* COMMENT */) {
+ nextNode = onMismatch();
+ }
+ else {
+ nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
+ }
+ }
+ else if (shapeFlag & 128 /* SUSPENSE */) {
+ nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
+ }
+ else {
+ warn$1('Invalid HostVNode type:', type, `(${typeof type})`);
+ }
+ }
+ if (ref != null) {
+ setRef(ref, null, parentSuspense, vnode);
+ }
+ return nextNode;
+ };
+ const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
+ optimized = optimized || !!vnode.dynamicChildren;
+ const { type, props, patchFlag, shapeFlag, dirs } = vnode;
+ // #4006 for form elements with non-string v-model value bindings
+ // e.g. ,
+ const forcePatchValue = (type === 'input' && dirs) || type === 'option';
+ // skip props & children if this is hoisted static nodes
+ if (forcePatchValue || patchFlag !== -1 /* HOISTED */) {
+ if (dirs) {
+ invokeDirectiveHook(vnode, null, parentComponent, 'created');
+ }
+ // props
+ if (props) {
+ if (forcePatchValue ||
+ !optimized ||
+ patchFlag & (16 /* FULL_PROPS */ | 32 /* HYDRATE_EVENTS */)) {
+ for (const key in props) {
+ if ((forcePatchValue && key.endsWith('value')) ||
+ (isOn(key) && !isReservedProp(key))) {
+ patchProp(el, key, null, props[key]);
+ }
+ }
+ }
+ else if (props.onClick) {
+ // Fast path for click listeners (which is most often) to avoid
+ // iterating through props.
+ patchProp(el, 'onClick', null, props.onClick);
+ }
+ }
+ // vnode / directive hooks
+ let vnodeHooks;
+ if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
+ invokeVNodeHook(vnodeHooks, parentComponent, vnode);
+ }
+ if (dirs) {
+ invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
+ }
+ if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
+ queueEffectWithSuspense(() => {
+ vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
+ dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
+ }, parentSuspense);
+ }
+ // children
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
+ // skip if element has innerHTML / textContent
+ !(props && (props.innerHTML || props.textContent))) {
+ let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
+ let hasWarned = false;
+ while (next) {
+ hasMismatch = true;
+ if (!hasWarned) {
+ warn$1(`Hydration children mismatch in <${vnode.type}>: ` +
+ `server rendered element contains more child nodes than client vdom.`);
+ hasWarned = true;
+ }
+ // The SSRed DOM contains more nodes than it should. Remove them.
+ const cur = next;
+ next = next.nextSibling;
+ remove(cur);
+ }
+ }
+ else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
+ if (el.textContent !== vnode.children) {
+ hasMismatch = true;
+ warn$1(`Hydration text content mismatch in <${vnode.type}>:\n` +
+ `- Client: ${el.textContent}\n` +
+ `- Server: ${vnode.children}`);
+ el.textContent = vnode.children;
+ }
+ }
+ }
+ return el.nextSibling;
+ };
+ const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
+ optimized = optimized || !!parentVNode.dynamicChildren;
+ const children = parentVNode.children;
+ const l = children.length;
+ let hasWarned = false;
+ for (let i = 0; i < l; i++) {
+ const vnode = optimized
+ ? children[i]
+ : (children[i] = normalizeVNode(children[i]));
+ if (node) {
+ node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
+ }
+ else if (vnode.type === Text && !vnode.children) {
+ continue;
+ }
+ else {
+ hasMismatch = true;
+ if (!hasWarned) {
+ warn$1(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
+ `server rendered element contains fewer child nodes than client vdom.`);
+ hasWarned = true;
+ }
+ // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
+ patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
+ }
+ }
+ return node;
+ };
+ const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
+ const { slotScopeIds: fragmentSlotScopeIds } = vnode;
+ if (fragmentSlotScopeIds) {
+ slotScopeIds = slotScopeIds
+ ? slotScopeIds.concat(fragmentSlotScopeIds)
+ : fragmentSlotScopeIds;
+ }
+ const container = parentNode(node);
+ const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
+ if (next && isComment(next) && next.data === ']') {
+ return nextSibling((vnode.anchor = next));
+ }
+ else {
+ // fragment didn't hydrate successfully, since we didn't get a end anchor
+ // back. This should have led to node/children mismatch warnings.
+ hasMismatch = true;
+ // since the anchor is missing, we need to create one and insert it
+ insert((vnode.anchor = createComment(`]`)), container, next);
+ return next;
+ }
+ };
+ const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
+ hasMismatch = true;
+ warn$1(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
+ ? `(text)`
+ : isComment(node) && node.data === '['
+ ? `(start of fragment)`
+ : ``);
+ vnode.el = null;
+ if (isFragment) {
+ // remove excessive fragment nodes
+ const end = locateClosingAsyncAnchor(node);
+ while (true) {
+ const next = nextSibling(node);
+ if (next && next !== end) {
+ remove(next);
+ }
+ else {
+ break;
+ }
+ }
+ }
+ const next = nextSibling(node);
+ const container = parentNode(node);
+ remove(node);
+ patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
+ return next;
+ };
+ const locateClosingAsyncAnchor = (node) => {
+ let match = 0;
+ while (node) {
+ node = nextSibling(node);
+ if (node && isComment(node)) {
+ if (node.data === '[')
+ match++;
+ if (node.data === ']') {
+ if (match === 0) {
+ return nextSibling(node);
+ }
+ else {
+ match--;
+ }
+ }
+ }
+ }
+ return node;
+ };
+ return [hydrate, hydrateNode];
+ }
+
+ let supported;
+ let perf;
+ function startMeasure(instance, type) {
+ if (instance.appContext.config.performance && isSupported()) {
+ perf.mark(`vue-${type}-${instance.uid}`);
+ }
+ {
+ devtoolsPerfStart(instance, type, supported ? perf.now() : Date.now());
+ }
+ }
+ function endMeasure(instance, type) {
+ if (instance.appContext.config.performance && isSupported()) {
+ const startTag = `vue-${type}-${instance.uid}`;
+ const endTag = startTag + `:end`;
+ perf.mark(endTag);
+ perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
+ perf.clearMarks(startTag);
+ perf.clearMarks(endTag);
+ }
+ {
+ devtoolsPerfEnd(instance, type, supported ? perf.now() : Date.now());
+ }
+ }
+ function isSupported() {
+ if (supported !== undefined) {
+ return supported;
+ }
+ /* eslint-disable no-restricted-globals */
+ if (typeof window !== 'undefined' && window.performance) {
+ supported = true;
+ perf = window.performance;
+ }
+ else {
+ supported = false;
+ }
+ /* eslint-enable no-restricted-globals */
+ return supported;
+ }
+
+ const queuePostRenderEffect = queueEffectWithSuspense
+ ;
+ /**
+ * The createRenderer function accepts two generic arguments:
+ * HostNode and HostElement, corresponding to Node and Element types in the
+ * host environment. For example, for runtime-dom, HostNode would be the DOM
+ * `Node` interface and HostElement would be the DOM `Element` interface.
+ *
+ * Custom renderers can pass in the platform specific types like this:
+ *
+ * ``` js
+ * const { render, createApp } = createRenderer({
+ * patchProp,
+ * ...nodeOps
+ * })
+ * ```
+ */
+ function createRenderer(options) {
+ return baseCreateRenderer(options);
+ }
+ // Separate API for creating hydration-enabled renderer.
+ // Hydration logic is only used when calling this function, making it
+ // tree-shakable.
+ function createHydrationRenderer(options) {
+ return baseCreateRenderer(options, createHydrationFunctions);
+ }
+ // implementation
+ function baseCreateRenderer(options, createHydrationFns) {
+ {
+ const target = getGlobalThis();
+ target.__VUE__ = true;
+ setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__);
+ }
+ const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
+ // Note: functions inside this closure should use `const xxx = () => {}`
+ // style in order to prevent being inlined by minifiers.
+ const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => {
+ if (n1 === n2) {
+ return;
+ }
+ // patching & not same type, unmount old tree
+ if (n1 && !isSameVNodeType(n1, n2)) {
+ anchor = getNextHostNode(n1);
+ unmount(n1, parentComponent, parentSuspense, true);
+ n1 = null;
+ }
+ if (n2.patchFlag === -2 /* BAIL */) {
+ optimized = false;
+ n2.dynamicChildren = null;
+ }
+ const { type, ref, shapeFlag } = n2;
+ switch (type) {
+ case Text:
+ processText(n1, n2, container, anchor);
+ break;
+ case Comment:
+ processCommentNode(n1, n2, container, anchor);
+ break;
+ case Static:
+ if (n1 == null) {
+ mountStaticNode(n2, container, anchor, isSVG);
+ }
+ else {
+ patchStaticNode(n1, n2, container, isSVG);
+ }
+ break;
+ case Fragment:
+ processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ break;
+ default:
+ if (shapeFlag & 1 /* ELEMENT */) {
+ processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else if (shapeFlag & 6 /* COMPONENT */) {
+ processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else if (shapeFlag & 64 /* TELEPORT */) {
+ type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
+ }
+ else if (shapeFlag & 128 /* SUSPENSE */) {
+ type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
+ }
+ else {
+ warn$1('Invalid VNode type:', type, `(${typeof type})`);
+ }
+ }
+ // set ref
+ if (ref != null && parentComponent) {
+ setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
+ }
+ };
+ const processText = (n1, n2, container, anchor) => {
+ if (n1 == null) {
+ hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
+ }
+ else {
+ const el = (n2.el = n1.el);
+ if (n2.children !== n1.children) {
+ hostSetText(el, n2.children);
+ }
+ }
+ };
+ const processCommentNode = (n1, n2, container, anchor) => {
+ if (n1 == null) {
+ hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
+ }
+ else {
+ // there's no support for dynamic comments
+ n2.el = n1.el;
+ }
+ };
+ const mountStaticNode = (n2, container, anchor, isSVG) => {
+ [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
+ };
+ /**
+ * Dev / HMR only
+ */
+ const patchStaticNode = (n1, n2, container, isSVG) => {
+ // static nodes are only patched during dev for HMR
+ if (n2.children !== n1.children) {
+ const anchor = hostNextSibling(n1.anchor);
+ // remove existing
+ removeStaticNode(n1);
+ [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
+ }
+ else {
+ n2.el = n1.el;
+ n2.anchor = n1.anchor;
+ }
+ };
+ const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
+ let next;
+ while (el && el !== anchor) {
+ next = hostNextSibling(el);
+ hostInsert(el, container, nextSibling);
+ el = next;
+ }
+ hostInsert(anchor, container, nextSibling);
+ };
+ const removeStaticNode = ({ el, anchor }) => {
+ let next;
+ while (el && el !== anchor) {
+ next = hostNextSibling(el);
+ hostRemove(el);
+ el = next;
+ }
+ hostRemove(anchor);
+ };
+ const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
+ isSVG = isSVG || n2.type === 'svg';
+ if (n1 == null) {
+ mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else {
+ patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ };
+ const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
+ let el;
+ let vnodeHook;
+ const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
+ {
+ el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
+ // mount children first, since some props may rely on child content
+ // being already rendered, e.g. ``
+ if (shapeFlag & 8 /* TEXT_CHILDREN */) {
+ hostSetElementText(el, vnode.children);
+ }
+ else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
+ }
+ if (dirs) {
+ invokeDirectiveHook(vnode, null, parentComponent, 'created');
+ }
+ // props
+ if (props) {
+ for (const key in props) {
+ if (key !== 'value' && !isReservedProp(key)) {
+ hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
+ }
+ }
+ /**
+ * Special case for setting value on DOM elements:
+ * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
+ * - it needs to be forced (#1471)
+ * #2353 proposes adding another renderer option to configure this, but
+ * the properties affects are so finite it is worth special casing it
+ * here to reduce the complexity. (Special casing it also should not
+ * affect non-DOM renderers)
+ */
+ if ('value' in props) {
+ hostPatchProp(el, 'value', null, props.value);
+ }
+ if ((vnodeHook = props.onVnodeBeforeMount)) {
+ invokeVNodeHook(vnodeHook, parentComponent, vnode);
+ }
+ }
+ // scopeId
+ setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
+ }
+ {
+ Object.defineProperty(el, '__vnode', {
+ value: vnode,
+ enumerable: false
+ });
+ Object.defineProperty(el, '__vueParentComponent', {
+ value: parentComponent,
+ enumerable: false
+ });
+ }
+ if (dirs) {
+ invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
+ }
+ // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
+ // #1689 For inside suspense + suspense resolved case, just call it
+ const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
+ transition &&
+ !transition.persisted;
+ if (needCallTransitionHooks) {
+ transition.beforeEnter(el);
+ }
+ hostInsert(el, container, anchor);
+ if ((vnodeHook = props && props.onVnodeMounted) ||
+ needCallTransitionHooks ||
+ dirs) {
+ queuePostRenderEffect(() => {
+ vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
+ needCallTransitionHooks && transition.enter(el);
+ dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
+ }, parentSuspense);
+ }
+ };
+ const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
+ if (scopeId) {
+ hostSetScopeId(el, scopeId);
+ }
+ if (slotScopeIds) {
+ for (let i = 0; i < slotScopeIds.length; i++) {
+ hostSetScopeId(el, slotScopeIds[i]);
+ }
+ }
+ if (parentComponent) {
+ let subTree = parentComponent.subTree;
+ if (subTree.patchFlag > 0 &&
+ subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
+ subTree =
+ filterSingleRoot(subTree.children) || subTree;
+ }
+ if (vnode === subTree) {
+ const parentVNode = parentComponent.vnode;
+ setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
+ }
+ }
+ };
+ const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
+ for (let i = start; i < children.length; i++) {
+ const child = (children[i] = optimized
+ ? cloneIfMounted(children[i])
+ : normalizeVNode(children[i]));
+ patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ };
+ const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
+ const el = (n2.el = n1.el);
+ let { patchFlag, dynamicChildren, dirs } = n2;
+ // #1426 take the old vnode's patch flag into account since user may clone a
+ // compiler-generated vnode, which de-opts to FULL_PROPS
+ patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
+ const oldProps = n1.props || EMPTY_OBJ;
+ const newProps = n2.props || EMPTY_OBJ;
+ let vnodeHook;
+ if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
+ invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
+ }
+ if (dirs) {
+ invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
+ }
+ if (isHmrUpdating) {
+ // HMR updated, force full diff
+ patchFlag = 0;
+ optimized = false;
+ dynamicChildren = null;
+ }
+ const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
+ if (dynamicChildren) {
+ patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
+ if (parentComponent && parentComponent.type.__hmrId) {
+ traverseStaticChildren(n1, n2);
+ }
+ }
+ else if (!optimized) {
+ // full diff
+ patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
+ }
+ if (patchFlag > 0) {
+ // the presence of a patchFlag means this element's render code was
+ // generated by the compiler and can take the fast path.
+ // in this path old node and new node are guaranteed to have the same shape
+ // (i.e. at the exact same position in the source template)
+ if (patchFlag & 16 /* FULL_PROPS */) {
+ // element props contain dynamic keys, full diff needed
+ patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
+ }
+ else {
+ // class
+ // this flag is matched when the element has dynamic class bindings.
+ if (patchFlag & 2 /* CLASS */) {
+ if (oldProps.class !== newProps.class) {
+ hostPatchProp(el, 'class', null, newProps.class, isSVG);
+ }
+ }
+ // style
+ // this flag is matched when the element has dynamic style bindings
+ if (patchFlag & 4 /* STYLE */) {
+ hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
+ }
+ // props
+ // This flag is matched when the element has dynamic prop/attr bindings
+ // other than class and style. The keys of dynamic prop/attrs are saved for
+ // faster iteration.
+ // Note dynamic keys like :[foo]="bar" will cause this optimization to
+ // bail out and go through a full diff because we need to unset the old key
+ if (patchFlag & 8 /* PROPS */) {
+ // if the flag is present then dynamicProps must be non-null
+ const propsToUpdate = n2.dynamicProps;
+ for (let i = 0; i < propsToUpdate.length; i++) {
+ const key = propsToUpdate[i];
+ const prev = oldProps[key];
+ const next = newProps[key];
+ // #1471 force patch value
+ if (next !== prev || key === 'value') {
+ hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
+ }
+ }
+ }
+ }
+ // text
+ // This flag is matched when the element has only dynamic text children.
+ if (patchFlag & 1 /* TEXT */) {
+ if (n1.children !== n2.children) {
+ hostSetElementText(el, n2.children);
+ }
+ }
+ }
+ else if (!optimized && dynamicChildren == null) {
+ // unoptimized, full diff
+ patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
+ }
+ if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
+ queuePostRenderEffect(() => {
+ vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
+ dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
+ }, parentSuspense);
+ }
+ };
+ // The fast path for blocks.
+ const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
+ for (let i = 0; i < newChildren.length; i++) {
+ const oldVNode = oldChildren[i];
+ const newVNode = newChildren[i];
+ // Determine the container (parent element) for the patch.
+ const container =
+ // oldVNode may be an errored async setup() component inside Suspense
+ // which will not have a mounted element
+ oldVNode.el &&
+ // - In the case of a Fragment, we need to provide the actual parent
+ // of the Fragment itself so it can move its children.
+ (oldVNode.type === Fragment ||
+ // - In the case of different nodes, there is going to be a replacement
+ // which also requires the correct parent container
+ !isSameVNodeType(oldVNode, newVNode) ||
+ // - In the case of a component, it could contain anything.
+ oldVNode.shapeFlag & (6 /* COMPONENT */ | 64 /* TELEPORT */))
+ ? hostParentNode(oldVNode.el)
+ : // In other cases, the parent container is not actually used so we
+ // just pass the block element here to avoid a DOM parentNode call.
+ fallbackContainer;
+ patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
+ }
+ };
+ const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
+ if (oldProps !== newProps) {
+ for (const key in newProps) {
+ // empty string is not valid prop
+ if (isReservedProp(key))
+ continue;
+ const next = newProps[key];
+ const prev = oldProps[key];
+ // defer patching value
+ if (next !== prev && key !== 'value') {
+ hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
+ }
+ }
+ if (oldProps !== EMPTY_OBJ) {
+ for (const key in oldProps) {
+ if (!isReservedProp(key) && !(key in newProps)) {
+ hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
+ }
+ }
+ }
+ if ('value' in newProps) {
+ hostPatchProp(el, 'value', oldProps.value, newProps.value);
+ }
+ }
+ };
+ const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
+ const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
+ const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
+ let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
+ if (isHmrUpdating) {
+ // HMR updated, force full diff
+ patchFlag = 0;
+ optimized = false;
+ dynamicChildren = null;
+ }
+ // check if this is a slot fragment with :slotted scope ids
+ if (fragmentSlotScopeIds) {
+ slotScopeIds = slotScopeIds
+ ? slotScopeIds.concat(fragmentSlotScopeIds)
+ : fragmentSlotScopeIds;
+ }
+ if (n1 == null) {
+ hostInsert(fragmentStartAnchor, container, anchor);
+ hostInsert(fragmentEndAnchor, container, anchor);
+ // a fragment can only have array children
+ // since they are either generated by the compiler, or implicitly created
+ // from arrays.
+ mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else {
+ if (patchFlag > 0 &&
+ patchFlag & 64 /* STABLE_FRAGMENT */ &&
+ dynamicChildren &&
+ // #2715 the previous fragment could've been a BAILed one as a result
+ // of renderSlot() with no valid children
+ n1.dynamicChildren) {
+ // a stable fragment (template root or ) doesn't need to
+ // patch children order, but it may contain dynamicChildren.
+ patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
+ if (parentComponent && parentComponent.type.__hmrId) {
+ traverseStaticChildren(n1, n2);
+ }
+ else if (
+ // #2080 if the stable fragment has a key, it's a that may
+ // get moved around. Make sure all root level vnodes inherit el.
+ // #2134 or if it's a component root, it may also get moved around
+ // as the component is being moved.
+ n2.key != null ||
+ (parentComponent && n2 === parentComponent.subTree)) {
+ traverseStaticChildren(n1, n2, true /* shallow */);
+ }
+ }
+ else {
+ // keyed / unkeyed, or manual fragments.
+ // for keyed & unkeyed, since they are compiler generated from v-for,
+ // each child is guaranteed to be a block so the fragment will never
+ // have dynamicChildren.
+ patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ }
+ };
+ const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
+ n2.slotScopeIds = slotScopeIds;
+ if (n1 == null) {
+ if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
+ parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
+ }
+ else {
+ mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
+ }
+ }
+ else {
+ updateComponent(n1, n2, optimized);
+ }
+ };
+ const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
+ const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
+ if (instance.type.__hmrId) {
+ registerHMR(instance);
+ }
+ {
+ pushWarningContext(initialVNode);
+ startMeasure(instance, `mount`);
+ }
+ // inject renderer internals for keepAlive
+ if (isKeepAlive(initialVNode)) {
+ instance.ctx.renderer = internals;
+ }
+ // resolve props and slots for setup context
+ {
+ {
+ startMeasure(instance, `init`);
+ }
+ setupComponent(instance);
+ {
+ endMeasure(instance, `init`);
+ }
+ }
+ // setup() is async. This component relies on async logic to be resolved
+ // before proceeding
+ if (instance.asyncDep) {
+ parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
+ // Give it a placeholder if this is not hydration
+ // TODO handle self-defined fallback
+ if (!initialVNode.el) {
+ const placeholder = (instance.subTree = createVNode(Comment));
+ processCommentNode(null, placeholder, container, anchor);
+ }
+ return;
+ }
+ setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
+ {
+ popWarningContext();
+ endMeasure(instance, `mount`);
+ }
+ };
+ const updateComponent = (n1, n2, optimized) => {
+ const instance = (n2.component = n1.component);
+ if (shouldUpdateComponent(n1, n2, optimized)) {
+ if (instance.asyncDep &&
+ !instance.asyncResolved) {
+ // async & still pending - just update props and slots
+ // since the component's reactive effect for render isn't set-up yet
+ {
+ pushWarningContext(n2);
+ }
+ updateComponentPreRender(instance, n2, optimized);
+ {
+ popWarningContext();
+ }
+ return;
+ }
+ else {
+ // normal update
+ instance.next = n2;
+ // in case the child component is also queued, remove it to avoid
+ // double updating the same child component in the same flush.
+ invalidateJob(instance.update);
+ // instance.update is the reactive effect.
+ instance.update();
+ }
+ }
+ else {
+ // no update needed. just copy over properties
+ n2.component = n1.component;
+ n2.el = n1.el;
+ instance.vnode = n2;
+ }
+ };
+ const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
+ const componentUpdateFn = () => {
+ if (!instance.isMounted) {
+ let vnodeHook;
+ const { el, props } = initialVNode;
+ const { bm, m, parent } = instance;
+ const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
+ effect.allowRecurse = false;
+ // beforeMount hook
+ if (bm) {
+ invokeArrayFns(bm);
+ }
+ // onVnodeBeforeMount
+ if (!isAsyncWrapperVNode &&
+ (vnodeHook = props && props.onVnodeBeforeMount)) {
+ invokeVNodeHook(vnodeHook, parent, initialVNode);
+ }
+ effect.allowRecurse = true;
+ if (el && hydrateNode) {
+ // vnode has adopted host node - perform hydration instead of mount.
+ const hydrateSubTree = () => {
+ {
+ startMeasure(instance, `render`);
+ }
+ instance.subTree = renderComponentRoot(instance);
+ {
+ endMeasure(instance, `render`);
+ }
+ {
+ startMeasure(instance, `hydrate`);
+ }
+ hydrateNode(el, instance.subTree, instance, parentSuspense, null);
+ {
+ endMeasure(instance, `hydrate`);
+ }
+ };
+ if (isAsyncWrapperVNode) {
+ initialVNode.type.__asyncLoader().then(
+ // note: we are moving the render call into an async callback,
+ // which means it won't track dependencies - but it's ok because
+ // a server-rendered async wrapper is already in resolved state
+ // and it will never need to change.
+ () => !instance.isUnmounted && hydrateSubTree());
+ }
+ else {
+ hydrateSubTree();
+ }
+ }
+ else {
+ {
+ startMeasure(instance, `render`);
+ }
+ const subTree = (instance.subTree = renderComponentRoot(instance));
+ {
+ endMeasure(instance, `render`);
+ }
+ {
+ startMeasure(instance, `patch`);
+ }
+ patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
+ {
+ endMeasure(instance, `patch`);
+ }
+ initialVNode.el = subTree.el;
+ }
+ // mounted hook
+ if (m) {
+ queuePostRenderEffect(m, parentSuspense);
+ }
+ // onVnodeMounted
+ if (!isAsyncWrapperVNode &&
+ (vnodeHook = props && props.onVnodeMounted)) {
+ const scopedInitialVNode = initialVNode;
+ queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
+ }
+ // activated hook for keep-alive roots.
+ // #1742 activated hook must be accessed after first render
+ // since the hook may be injected by a child keep-alive
+ if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
+ instance.a && queuePostRenderEffect(instance.a, parentSuspense);
+ }
+ instance.isMounted = true;
+ {
+ devtoolsComponentAdded(instance);
+ }
+ // #2458: deference mount-only object parameters to prevent memleaks
+ initialVNode = container = anchor = null;
+ }
+ else {
+ // updateComponent
+ // This is triggered by mutation of component's own state (next: null)
+ // OR parent calling processComponent (next: VNode)
+ let { next, bu, u, parent, vnode } = instance;
+ let originNext = next;
+ let vnodeHook;
+ {
+ pushWarningContext(next || instance.vnode);
+ }
+ // Disallow component effect recursion during pre-lifecycle hooks.
+ effect.allowRecurse = false;
+ if (next) {
+ next.el = vnode.el;
+ updateComponentPreRender(instance, next, optimized);
+ }
+ else {
+ next = vnode;
+ }
+ // beforeUpdate hook
+ if (bu) {
+ invokeArrayFns(bu);
+ }
+ // onVnodeBeforeUpdate
+ if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
+ invokeVNodeHook(vnodeHook, parent, next, vnode);
+ }
+ effect.allowRecurse = true;
+ // render
+ {
+ startMeasure(instance, `render`);
+ }
+ const nextTree = renderComponentRoot(instance);
+ {
+ endMeasure(instance, `render`);
+ }
+ const prevTree = instance.subTree;
+ instance.subTree = nextTree;
+ {
+ startMeasure(instance, `patch`);
+ }
+ patch(prevTree, nextTree,
+ // parent may have changed if it's in a teleport
+ hostParentNode(prevTree.el),
+ // anchor may have changed if it's in a fragment
+ getNextHostNode(prevTree), instance, parentSuspense, isSVG);
+ {
+ endMeasure(instance, `patch`);
+ }
+ next.el = nextTree.el;
+ if (originNext === null) {
+ // self-triggered update. In case of HOC, update parent component
+ // vnode el. HOC is indicated by parent instance's subTree pointing
+ // to child component's vnode
+ updateHOCHostEl(instance, nextTree.el);
+ }
+ // updated hook
+ if (u) {
+ queuePostRenderEffect(u, parentSuspense);
+ }
+ // onVnodeUpdated
+ if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
+ queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
+ }
+ {
+ devtoolsComponentUpdated(instance);
+ }
+ {
+ popWarningContext();
+ }
+ }
+ };
+ // create reactive effect for rendering
+ const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
+ );
+ const update = (instance.update = effect.run.bind(effect));
+ update.id = instance.uid;
+ // allowRecurse
+ // #1801, #2043 component render effects should allow recursive updates
+ effect.allowRecurse = update.allowRecurse = true;
+ {
+ effect.onTrack = instance.rtc
+ ? e => invokeArrayFns(instance.rtc, e)
+ : void 0;
+ effect.onTrigger = instance.rtg
+ ? e => invokeArrayFns(instance.rtg, e)
+ : void 0;
+ // @ts-ignore (for scheduler)
+ update.ownerInstance = instance;
+ }
+ update();
+ };
+ const updateComponentPreRender = (instance, nextVNode, optimized) => {
+ nextVNode.component = instance;
+ const prevProps = instance.vnode.props;
+ instance.vnode = nextVNode;
+ instance.next = null;
+ updateProps(instance, nextVNode.props, prevProps, optimized);
+ updateSlots(instance, nextVNode.children, optimized);
+ pauseTracking();
+ // props update may have triggered pre-flush watchers.
+ // flush them before the render update.
+ flushPreFlushCbs(undefined, instance.update);
+ resetTracking();
+ };
+ const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
+ const c1 = n1 && n1.children;
+ const prevShapeFlag = n1 ? n1.shapeFlag : 0;
+ const c2 = n2.children;
+ const { patchFlag, shapeFlag } = n2;
+ // fast path
+ if (patchFlag > 0) {
+ if (patchFlag & 128 /* KEYED_FRAGMENT */) {
+ // this could be either fully-keyed or mixed (some keyed some not)
+ // presence of patchFlag means children are guaranteed to be arrays
+ patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ return;
+ }
+ else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
+ // unkeyed
+ patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ return;
+ }
+ }
+ // children has 3 possibilities: text, array or no children.
+ if (shapeFlag & 8 /* TEXT_CHILDREN */) {
+ // text children fast path
+ if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
+ unmountChildren(c1, parentComponent, parentSuspense);
+ }
+ if (c2 !== c1) {
+ hostSetElementText(container, c2);
+ }
+ }
+ else {
+ if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
+ // prev children was array
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ // two arrays, cannot assume anything, do full diff
+ patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else {
+ // no new children, just unmount old
+ unmountChildren(c1, parentComponent, parentSuspense, true);
+ }
+ }
+ else {
+ // prev children was text OR null
+ // new children is array OR null
+ if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
+ hostSetElementText(container, '');
+ }
+ // mount new if array
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ }
+ }
+ };
+ const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
+ c1 = c1 || EMPTY_ARR;
+ c2 = c2 || EMPTY_ARR;
+ const oldLength = c1.length;
+ const newLength = c2.length;
+ const commonLength = Math.min(oldLength, newLength);
+ let i;
+ for (i = 0; i < commonLength; i++) {
+ const nextChild = (c2[i] = optimized
+ ? cloneIfMounted(c2[i])
+ : normalizeVNode(c2[i]));
+ patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ if (oldLength > newLength) {
+ // remove old
+ unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
+ }
+ else {
+ // mount new
+ mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
+ }
+ };
+ // can be all-keyed or mixed
+ const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
+ let i = 0;
+ const l2 = c2.length;
+ let e1 = c1.length - 1; // prev ending index
+ let e2 = l2 - 1; // next ending index
+ // 1. sync from start
+ // (a b) c
+ // (a b) d e
+ while (i <= e1 && i <= e2) {
+ const n1 = c1[i];
+ const n2 = (c2[i] = optimized
+ ? cloneIfMounted(c2[i])
+ : normalizeVNode(c2[i]));
+ if (isSameVNodeType(n1, n2)) {
+ patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else {
+ break;
+ }
+ i++;
+ }
+ // 2. sync from end
+ // a (b c)
+ // d e (b c)
+ while (i <= e1 && i <= e2) {
+ const n1 = c1[e1];
+ const n2 = (c2[e2] = optimized
+ ? cloneIfMounted(c2[e2])
+ : normalizeVNode(c2[e2]));
+ if (isSameVNodeType(n1, n2)) {
+ patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else {
+ break;
+ }
+ e1--;
+ e2--;
+ }
+ // 3. common sequence + mount
+ // (a b)
+ // (a b) c
+ // i = 2, e1 = 1, e2 = 2
+ // (a b)
+ // c (a b)
+ // i = 0, e1 = -1, e2 = 0
+ if (i > e1) {
+ if (i <= e2) {
+ const nextPos = e2 + 1;
+ const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
+ while (i <= e2) {
+ patch(null, (c2[i] = optimized
+ ? cloneIfMounted(c2[i])
+ : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ i++;
+ }
+ }
+ }
+ // 4. common sequence + unmount
+ // (a b) c
+ // (a b)
+ // i = 2, e1 = 2, e2 = 1
+ // a (b c)
+ // (b c)
+ // i = 0, e1 = 0, e2 = -1
+ else if (i > e2) {
+ while (i <= e1) {
+ unmount(c1[i], parentComponent, parentSuspense, true);
+ i++;
+ }
+ }
+ // 5. unknown sequence
+ // [i ... e1 + 1]: a b [c d e] f g
+ // [i ... e2 + 1]: a b [e d c h] f g
+ // i = 2, e1 = 4, e2 = 5
+ else {
+ const s1 = i; // prev starting index
+ const s2 = i; // next starting index
+ // 5.1 build key:index map for newChildren
+ const keyToNewIndexMap = new Map();
+ for (i = s2; i <= e2; i++) {
+ const nextChild = (c2[i] = optimized
+ ? cloneIfMounted(c2[i])
+ : normalizeVNode(c2[i]));
+ if (nextChild.key != null) {
+ if (keyToNewIndexMap.has(nextChild.key)) {
+ warn$1(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
+ }
+ keyToNewIndexMap.set(nextChild.key, i);
+ }
+ }
+ // 5.2 loop through old children left to be patched and try to patch
+ // matching nodes & remove nodes that are no longer present
+ let j;
+ let patched = 0;
+ const toBePatched = e2 - s2 + 1;
+ let moved = false;
+ // used to track whether any node has moved
+ let maxNewIndexSoFar = 0;
+ // works as Map
+ // Note that oldIndex is offset by +1
+ // and oldIndex = 0 is a special value indicating the new node has
+ // no corresponding old node.
+ // used for determining longest stable subsequence
+ const newIndexToOldIndexMap = new Array(toBePatched);
+ for (i = 0; i < toBePatched; i++)
+ newIndexToOldIndexMap[i] = 0;
+ for (i = s1; i <= e1; i++) {
+ const prevChild = c1[i];
+ if (patched >= toBePatched) {
+ // all new children have been patched so this can only be a removal
+ unmount(prevChild, parentComponent, parentSuspense, true);
+ continue;
+ }
+ let newIndex;
+ if (prevChild.key != null) {
+ newIndex = keyToNewIndexMap.get(prevChild.key);
+ }
+ else {
+ // key-less node, try to locate a key-less node of the same type
+ for (j = s2; j <= e2; j++) {
+ if (newIndexToOldIndexMap[j - s2] === 0 &&
+ isSameVNodeType(prevChild, c2[j])) {
+ newIndex = j;
+ break;
+ }
+ }
+ }
+ if (newIndex === undefined) {
+ unmount(prevChild, parentComponent, parentSuspense, true);
+ }
+ else {
+ newIndexToOldIndexMap[newIndex - s2] = i + 1;
+ if (newIndex >= maxNewIndexSoFar) {
+ maxNewIndexSoFar = newIndex;
+ }
+ else {
+ moved = true;
+ }
+ patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ patched++;
+ }
+ }
+ // 5.3 move and mount
+ // generate longest stable subsequence only when nodes have moved
+ const increasingNewIndexSequence = moved
+ ? getSequence(newIndexToOldIndexMap)
+ : EMPTY_ARR;
+ j = increasingNewIndexSequence.length - 1;
+ // looping backwards so that we can use last patched node as anchor
+ for (i = toBePatched - 1; i >= 0; i--) {
+ const nextIndex = s2 + i;
+ const nextChild = c2[nextIndex];
+ const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
+ if (newIndexToOldIndexMap[i] === 0) {
+ // mount new
+ patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ else if (moved) {
+ // move if:
+ // There is no stable subsequence (e.g. a reverse)
+ // OR current node is not among the stable sequence
+ if (j < 0 || i !== increasingNewIndexSequence[j]) {
+ move(nextChild, container, anchor, 2 /* REORDER */);
+ }
+ else {
+ j--;
+ }
+ }
+ }
+ }
+ };
+ const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
+ const { el, type, transition, children, shapeFlag } = vnode;
+ if (shapeFlag & 6 /* COMPONENT */) {
+ move(vnode.component.subTree, container, anchor, moveType);
+ return;
+ }
+ if (shapeFlag & 128 /* SUSPENSE */) {
+ vnode.suspense.move(container, anchor, moveType);
+ return;
+ }
+ if (shapeFlag & 64 /* TELEPORT */) {
+ type.move(vnode, container, anchor, internals);
+ return;
+ }
+ if (type === Fragment) {
+ hostInsert(el, container, anchor);
+ for (let i = 0; i < children.length; i++) {
+ move(children[i], container, anchor, moveType);
+ }
+ hostInsert(vnode.anchor, container, anchor);
+ return;
+ }
+ if (type === Static) {
+ moveStaticNode(vnode, container, anchor);
+ return;
+ }
+ // single nodes
+ const needTransition = moveType !== 2 /* REORDER */ &&
+ shapeFlag & 1 /* ELEMENT */ &&
+ transition;
+ if (needTransition) {
+ if (moveType === 0 /* ENTER */) {
+ transition.beforeEnter(el);
+ hostInsert(el, container, anchor);
+ queuePostRenderEffect(() => transition.enter(el), parentSuspense);
+ }
+ else {
+ const { leave, delayLeave, afterLeave } = transition;
+ const remove = () => hostInsert(el, container, anchor);
+ const performLeave = () => {
+ leave(el, () => {
+ remove();
+ afterLeave && afterLeave();
+ });
+ };
+ if (delayLeave) {
+ delayLeave(el, remove, performLeave);
+ }
+ else {
+ performLeave();
+ }
+ }
+ }
+ else {
+ hostInsert(el, container, anchor);
+ }
+ };
+ const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
+ const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
+ // unset ref
+ if (ref != null) {
+ setRef(ref, null, parentSuspense, vnode, true);
+ }
+ if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
+ parentComponent.ctx.deactivate(vnode);
+ return;
+ }
+ const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
+ const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
+ let vnodeHook;
+ if (shouldInvokeVnodeHook &&
+ (vnodeHook = props && props.onVnodeBeforeUnmount)) {
+ invokeVNodeHook(vnodeHook, parentComponent, vnode);
+ }
+ if (shapeFlag & 6 /* COMPONENT */) {
+ unmountComponent(vnode.component, parentSuspense, doRemove);
+ }
+ else {
+ if (shapeFlag & 128 /* SUSPENSE */) {
+ vnode.suspense.unmount(parentSuspense, doRemove);
+ return;
+ }
+ if (shouldInvokeDirs) {
+ invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
+ }
+ if (shapeFlag & 64 /* TELEPORT */) {
+ vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
+ }
+ else if (dynamicChildren &&
+ // #1153: fast path should not be taken for non-stable (v-for) fragments
+ (type !== Fragment ||
+ (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
+ // fast path for block nodes: only need to unmount dynamic children.
+ unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
+ }
+ else if ((type === Fragment &&
+ patchFlag &
+ (128 /* KEYED_FRAGMENT */ | 256 /* UNKEYED_FRAGMENT */)) ||
+ (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
+ unmountChildren(children, parentComponent, parentSuspense);
+ }
+ if (doRemove) {
+ remove(vnode);
+ }
+ }
+ if ((shouldInvokeVnodeHook &&
+ (vnodeHook = props && props.onVnodeUnmounted)) ||
+ shouldInvokeDirs) {
+ queuePostRenderEffect(() => {
+ vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
+ shouldInvokeDirs &&
+ invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
+ }, parentSuspense);
+ }
+ };
+ const remove = vnode => {
+ const { type, el, anchor, transition } = vnode;
+ if (type === Fragment) {
+ removeFragment(el, anchor);
+ return;
+ }
+ if (type === Static) {
+ removeStaticNode(vnode);
+ return;
+ }
+ const performRemove = () => {
+ hostRemove(el);
+ if (transition && !transition.persisted && transition.afterLeave) {
+ transition.afterLeave();
+ }
+ };
+ if (vnode.shapeFlag & 1 /* ELEMENT */ &&
+ transition &&
+ !transition.persisted) {
+ const { leave, delayLeave } = transition;
+ const performLeave = () => leave(el, performRemove);
+ if (delayLeave) {
+ delayLeave(vnode.el, performRemove, performLeave);
+ }
+ else {
+ performLeave();
+ }
+ }
+ else {
+ performRemove();
+ }
+ };
+ const removeFragment = (cur, end) => {
+ // For fragments, directly remove all contained DOM nodes.
+ // (fragment child nodes cannot have transition)
+ let next;
+ while (cur !== end) {
+ next = hostNextSibling(cur);
+ hostRemove(cur);
+ cur = next;
+ }
+ hostRemove(end);
+ };
+ const unmountComponent = (instance, parentSuspense, doRemove) => {
+ if (instance.type.__hmrId) {
+ unregisterHMR(instance);
+ }
+ const { bum, scope, update, subTree, um } = instance;
+ // beforeUnmount hook
+ if (bum) {
+ invokeArrayFns(bum);
+ }
+ // stop effects in component scope
+ scope.stop();
+ // update may be null if a component is unmounted before its async
+ // setup has resolved.
+ if (update) {
+ // so that scheduler will no longer invoke it
+ update.active = false;
+ unmount(subTree, instance, parentSuspense, doRemove);
+ }
+ // unmounted hook
+ if (um) {
+ queuePostRenderEffect(um, parentSuspense);
+ }
+ queuePostRenderEffect(() => {
+ instance.isUnmounted = true;
+ }, parentSuspense);
+ // A component with async dep inside a pending suspense is unmounted before
+ // its async dep resolves. This should remove the dep from the suspense, and
+ // cause the suspense to resolve immediately if that was the last dep.
+ if (parentSuspense &&
+ parentSuspense.pendingBranch &&
+ !parentSuspense.isUnmounted &&
+ instance.asyncDep &&
+ !instance.asyncResolved &&
+ instance.suspenseId === parentSuspense.pendingId) {
+ parentSuspense.deps--;
+ if (parentSuspense.deps === 0) {
+ parentSuspense.resolve();
+ }
+ }
+ {
+ devtoolsComponentRemoved(instance);
+ }
+ };
+ const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
+ for (let i = start; i < children.length; i++) {
+ unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
+ }
+ };
+ const getNextHostNode = vnode => {
+ if (vnode.shapeFlag & 6 /* COMPONENT */) {
+ return getNextHostNode(vnode.component.subTree);
+ }
+ if (vnode.shapeFlag & 128 /* SUSPENSE */) {
+ return vnode.suspense.next();
+ }
+ return hostNextSibling((vnode.anchor || vnode.el));
+ };
+ const render = (vnode, container, isSVG) => {
+ if (vnode == null) {
+ if (container._vnode) {
+ unmount(container._vnode, null, null, true);
+ }
+ }
+ else {
+ patch(container._vnode || null, vnode, container, null, null, null, isSVG);
+ }
+ flushPostFlushCbs();
+ container._vnode = vnode;
+ };
+ const internals = {
+ p: patch,
+ um: unmount,
+ m: move,
+ r: remove,
+ mt: mountComponent,
+ mc: mountChildren,
+ pc: patchChildren,
+ pbc: patchBlockChildren,
+ n: getNextHostNode,
+ o: options
+ };
+ let hydrate;
+ let hydrateNode;
+ if (createHydrationFns) {
+ [hydrate, hydrateNode] = createHydrationFns(internals);
+ }
+ return {
+ render,
+ hydrate,
+ createApp: createAppAPI(render, hydrate)
+ };
+ }
+ function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
+ if (isArray(rawRef)) {
+ rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
+ return;
+ }
+ if (isAsyncWrapper(vnode) && !isUnmount) {
+ // when mounting async components, nothing needs to be done,
+ // because the template ref is forwarded to inner component
+ return;
+ }
+ const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
+ : vnode.el;
+ const value = isUnmount ? null : refValue;
+ const { i: owner, r: ref } = rawRef;
+ if (!owner) {
+ warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
+ `A vnode with ref must be created inside the render function.`);
+ return;
+ }
+ const oldRef = oldRawRef && oldRawRef.r;
+ const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
+ const setupState = owner.setupState;
+ // dynamic ref changed. unset old ref
+ if (oldRef != null && oldRef !== ref) {
+ if (isString(oldRef)) {
+ refs[oldRef] = null;
+ if (hasOwn(setupState, oldRef)) {
+ setupState[oldRef] = null;
+ }
+ }
+ else if (isRef(oldRef)) {
+ oldRef.value = null;
+ }
+ }
+ if (isString(ref)) {
+ const doSet = () => {
+ {
+ refs[ref] = value;
+ }
+ if (hasOwn(setupState, ref)) {
+ setupState[ref] = value;
+ }
+ };
+ // #1789: for non-null values, set them after render
+ // null values means this is unmount and it should not overwrite another
+ // ref with the same key
+ if (value) {
+ doSet.id = -1;
+ queuePostRenderEffect(doSet, parentSuspense);
+ }
+ else {
+ doSet();
+ }
+ }
+ else if (isRef(ref)) {
+ const doSet = () => {
+ ref.value = value;
+ };
+ if (value) {
+ doSet.id = -1;
+ queuePostRenderEffect(doSet, parentSuspense);
+ }
+ else {
+ doSet();
+ }
+ }
+ else if (isFunction(ref)) {
+ callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
+ }
+ else {
+ warn$1('Invalid template ref type:', value, `(${typeof value})`);
+ }
+ }
+ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
+ callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
+ vnode,
+ prevVNode
+ ]);
+ }
+ /**
+ * #1156
+ * When a component is HMR-enabled, we need to make sure that all static nodes
+ * inside a block also inherit the DOM element from the previous tree so that
+ * HMR updates (which are full updates) can retrieve the element for patching.
+ *
+ * #2080
+ * Inside keyed `template` fragment static children, if a fragment is moved,
+ * the children will always moved so that need inherit el form previous nodes
+ * to ensure correct moved position.
+ */
+ function traverseStaticChildren(n1, n2, shallow = false) {
+ const ch1 = n1.children;
+ const ch2 = n2.children;
+ if (isArray(ch1) && isArray(ch2)) {
+ for (let i = 0; i < ch1.length; i++) {
+ // this is only called in the optimized path so array children are
+ // guaranteed to be vnodes
+ const c1 = ch1[i];
+ let c2 = ch2[i];
+ if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
+ if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
+ c2 = ch2[i] = cloneIfMounted(ch2[i]);
+ c2.el = c1.el;
+ }
+ if (!shallow)
+ traverseStaticChildren(c1, c2);
+ }
+ // also inherit for comment nodes, but not placeholders (e.g. v-if which
+ // would have received .el during block patch)
+ if (c2.type === Comment && !c2.el) {
+ c2.el = c1.el;
+ }
+ }
+ }
+ }
+ // https://en.wikipedia.org/wiki/Longest_increasing_subsequence
+ function getSequence(arr) {
+ const p = arr.slice();
+ const result = [0];
+ let i, j, u, v, c;
+ const len = arr.length;
+ for (i = 0; i < len; i++) {
+ const arrI = arr[i];
+ if (arrI !== 0) {
+ j = result[result.length - 1];
+ if (arr[j] < arrI) {
+ p[i] = j;
+ result.push(i);
+ continue;
+ }
+ u = 0;
+ v = result.length - 1;
+ while (u < v) {
+ c = (u + v) >> 1;
+ if (arr[result[c]] < arrI) {
+ u = c + 1;
+ }
+ else {
+ v = c;
+ }
+ }
+ if (arrI < arr[result[u]]) {
+ if (u > 0) {
+ p[i] = result[u - 1];
+ }
+ result[u] = i;
+ }
+ }
+ }
+ u = result.length;
+ v = result[u - 1];
+ while (u-- > 0) {
+ result[u] = v;
+ v = p[v];
+ }
+ return result;
+ }
+
+ const isTeleport = (type) => type.__isTeleport;
+ const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
+ const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
+ const resolveTarget = (props, select) => {
+ const targetSelector = props && props.to;
+ if (isString(targetSelector)) {
+ if (!select) {
+ warn$1(`Current renderer does not support string target for Teleports. ` +
+ `(missing querySelector renderer option)`);
+ return null;
+ }
+ else {
+ const target = select(targetSelector);
+ if (!target) {
+ warn$1(`Failed to locate Teleport target with selector "${targetSelector}". ` +
+ `Note the target element must exist before the component is mounted - ` +
+ `i.e. the target cannot be rendered by the component itself, and ` +
+ `ideally should be outside of the entire Vue component tree.`);
+ }
+ return target;
+ }
+ }
+ else {
+ if (!targetSelector && !isTeleportDisabled(props)) {
+ warn$1(`Invalid Teleport target: ${targetSelector}`);
+ }
+ return targetSelector;
+ }
+ };
+ const TeleportImpl = {
+ __isTeleport: true,
+ process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
+ const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
+ const disabled = isTeleportDisabled(n2.props);
+ let { shapeFlag, children, dynamicChildren } = n2;
+ // #3302
+ // HMR updated, force full diff
+ if (isHmrUpdating) {
+ optimized = false;
+ dynamicChildren = null;
+ }
+ if (n1 == null) {
+ // insert anchors in the main view
+ const placeholder = (n2.el = createComment('teleport start')
+ );
+ const mainAnchor = (n2.anchor = createComment('teleport end')
+ );
+ insert(placeholder, container, anchor);
+ insert(mainAnchor, container, anchor);
+ const target = (n2.target = resolveTarget(n2.props, querySelector));
+ const targetAnchor = (n2.targetAnchor = createText(''));
+ if (target) {
+ insert(targetAnchor, target);
+ // #2652 we could be teleporting from a non-SVG tree into an SVG tree
+ isSVG = isSVG || isTargetSVG(target);
+ }
+ else if (!disabled) {
+ warn$1('Invalid Teleport target on mount:', target, `(${typeof target})`);
+ }
+ const mount = (container, anchor) => {
+ // Teleport *always* has Array children. This is enforced in both the
+ // compiler and vnode children normalization.
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
+ }
+ };
+ if (disabled) {
+ mount(container, mainAnchor);
+ }
+ else if (target) {
+ mount(target, targetAnchor);
+ }
+ }
+ else {
+ // update content
+ n2.el = n1.el;
+ const mainAnchor = (n2.anchor = n1.anchor);
+ const target = (n2.target = n1.target);
+ const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
+ const wasDisabled = isTeleportDisabled(n1.props);
+ const currentContainer = wasDisabled ? container : target;
+ const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
+ isSVG = isSVG || isTargetSVG(target);
+ if (dynamicChildren) {
+ // fast path when the teleport happens to be a block root
+ patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
+ // even in block tree mode we need to make sure all root-level nodes
+ // in the teleport inherit previous DOM references so that they can
+ // be moved in future patches.
+ traverseStaticChildren(n1, n2, true);
+ }
+ else if (!optimized) {
+ patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
+ }
+ if (disabled) {
+ if (!wasDisabled) {
+ // enabled -> disabled
+ // move into main container
+ moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
+ }
+ }
+ else {
+ // target changed
+ if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
+ const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
+ if (nextTarget) {
+ moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
+ }
+ else {
+ warn$1('Invalid Teleport target on update:', target, `(${typeof target})`);
+ }
+ }
+ else if (wasDisabled) {
+ // disabled -> enabled
+ // move into teleport target
+ moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
+ }
+ }
+ }
+ },
+ remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
+ const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
+ if (target) {
+ hostRemove(targetAnchor);
+ }
+ // an unmounted teleport should always remove its children if not disabled
+ if (doRemove || !isTeleportDisabled(props)) {
+ hostRemove(anchor);
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i];
+ unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
+ }
+ }
+ }
+ },
+ move: moveTeleport,
+ hydrate: hydrateTeleport
+ };
+ function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
+ // move target anchor if this is a target change.
+ if (moveType === 0 /* TARGET_CHANGE */) {
+ insert(vnode.targetAnchor, container, parentAnchor);
+ }
+ const { el, anchor, shapeFlag, children, props } = vnode;
+ const isReorder = moveType === 2 /* REORDER */;
+ // move main view anchor if this is a re-order.
+ if (isReorder) {
+ insert(el, container, parentAnchor);
+ }
+ // if this is a re-order and teleport is enabled (content is in target)
+ // do not move children. So the opposite is: only move children if this
+ // is not a reorder, or the teleport is disabled
+ if (!isReorder || isTeleportDisabled(props)) {
+ // Teleport has either Array children or no children.
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ for (let i = 0; i < children.length; i++) {
+ move(children[i], container, parentAnchor, 2 /* REORDER */);
+ }
+ }
+ }
+ // move main view anchor if this is a re-order.
+ if (isReorder) {
+ insert(anchor, container, parentAnchor);
+ }
+ }
+ function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
+ const target = (vnode.target = resolveTarget(vnode.props, querySelector));
+ if (target) {
+ // if multiple teleports rendered to the same target element, we need to
+ // pick up from where the last teleport finished instead of the first node
+ const targetNode = target._lpa || target.firstChild;
+ if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ if (isTeleportDisabled(vnode.props)) {
+ vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
+ vnode.targetAnchor = targetNode;
+ }
+ else {
+ vnode.anchor = nextSibling(node);
+ vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
+ }
+ target._lpa =
+ vnode.targetAnchor && nextSibling(vnode.targetAnchor);
+ }
+ }
+ return vnode.anchor && nextSibling(vnode.anchor);
+ }
+ // Force-casted public typing for h and TSX props inference
+ const Teleport = TeleportImpl;
+
+ const COMPONENTS = 'components';
+ const DIRECTIVES = 'directives';
+ /**
+ * @private
+ */
+ function resolveComponent(name, maybeSelfReference) {
+ return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
+ }
+ const NULL_DYNAMIC_COMPONENT = Symbol();
+ /**
+ * @private
+ */
+ function resolveDynamicComponent(component) {
+ if (isString(component)) {
+ return resolveAsset(COMPONENTS, component, false) || component;
+ }
+ else {
+ // invalid types will fallthrough to createVNode and raise warning
+ return (component || NULL_DYNAMIC_COMPONENT);
+ }
+ }
+ /**
+ * @private
+ */
+ function resolveDirective(name) {
+ return resolveAsset(DIRECTIVES, name);
+ }
+ // implementation
+ function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
+ const instance = currentRenderingInstance || currentInstance;
+ if (instance) {
+ const Component = instance.type;
+ // explicit self name has highest priority
+ if (type === COMPONENTS) {
+ const selfName = getComponentName(Component);
+ if (selfName &&
+ (selfName === name ||
+ selfName === camelize(name) ||
+ selfName === capitalize(camelize(name)))) {
+ return Component;
+ }
+ }
+ const res =
+ // local registration
+ // check instance[type] first which is resolved for options API
+ resolve(instance[type] || Component[type], name) ||
+ // global registration
+ resolve(instance.appContext[type], name);
+ if (!res && maybeSelfReference) {
+ // fallback to implicit self-reference
+ return Component;
+ }
+ if (warnMissing && !res) {
+ warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
+ }
+ return res;
+ }
+ else {
+ warn$1(`resolve${capitalize(type.slice(0, -1))} ` +
+ `can only be used in render() or setup().`);
+ }
+ }
+ function resolve(registry, name) {
+ return (registry &&
+ (registry[name] ||
+ registry[camelize(name)] ||
+ registry[capitalize(camelize(name))]));
+ }
+
+ const Fragment = Symbol('Fragment' );
+ const Text = Symbol('Text' );
+ const Comment = Symbol('Comment' );
+ const Static = Symbol('Static' );
+ // Since v-if and v-for are the two possible ways node structure can dynamically
+ // change, once we consider v-if branches and each v-for fragment a block, we
+ // can divide a template into nested blocks, and within each block the node
+ // structure would be stable. This allows us to skip most children diffing
+ // and only worry about the dynamic nodes (indicated by patch flags).
+ const blockStack = [];
+ let currentBlock = null;
+ /**
+ * Open a block.
+ * This must be called before `createBlock`. It cannot be part of `createBlock`
+ * because the children of the block are evaluated before `createBlock` itself
+ * is called. The generated code typically looks like this:
+ *
+ * ```js
+ * function render() {
+ * return (openBlock(),createBlock('div', null, [...]))
+ * }
+ * ```
+ * disableTracking is true when creating a v-for fragment block, since a v-for
+ * fragment always diffs its children.
+ *
+ * @private
+ */
+ function openBlock(disableTracking = false) {
+ blockStack.push((currentBlock = disableTracking ? null : []));
+ }
+ function closeBlock() {
+ blockStack.pop();
+ currentBlock = blockStack[blockStack.length - 1] || null;
+ }
+ // Whether we should be tracking dynamic child nodes inside a block.
+ // Only tracks when this value is > 0
+ // We are not using a simple boolean because this value may need to be
+ // incremented/decremented by nested usage of v-once (see below)
+ let isBlockTreeEnabled = 1;
+ /**
+ * Block tracking sometimes needs to be disabled, for example during the
+ * creation of a tree that needs to be cached by v-once. The compiler generates
+ * code like this:
+ *
+ * ``` js
+ * _cache[1] || (
+ * setBlockTracking(-1),
+ * _cache[1] = createVNode(...),
+ * setBlockTracking(1),
+ * _cache[1]
+ * )
+ * ```
+ *
+ * @private
+ */
+ function setBlockTracking(value) {
+ isBlockTreeEnabled += value;
+ }
+ function setupBlock(vnode) {
+ // save current block children on the block vnode
+ vnode.dynamicChildren =
+ isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
+ // close block
+ closeBlock();
+ // a block is always going to be patched, so track it as a child of its
+ // parent block
+ if (isBlockTreeEnabled > 0 && currentBlock) {
+ currentBlock.push(vnode);
+ }
+ return vnode;
+ }
+ /**
+ * @private
+ */
+ function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
+ return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
+ }
+ /**
+ * Create a block root vnode. Takes the same exact arguments as `createVNode`.
+ * A block root keeps track of dynamic nodes within the block in the
+ * `dynamicChildren` array.
+ *
+ * @private
+ */
+ function createBlock(type, props, children, patchFlag, dynamicProps) {
+ return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
+ }
+ function isVNode(value) {
+ return value ? value.__v_isVNode === true : false;
+ }
+ function isSameVNodeType(n1, n2) {
+ if (n2.shapeFlag & 6 /* COMPONENT */ &&
+ hmrDirtyComponents.has(n2.type)) {
+ // HMR only: if the component has been hot-updated, force a reload.
+ return false;
+ }
+ return n1.type === n2.type && n1.key === n2.key;
+ }
+ let vnodeArgsTransformer;
+ /**
+ * Internal API for registering an arguments transform for createVNode
+ * used for creating stubs in the test-utils
+ * It is *internal* but needs to be exposed for test-utils to pick up proper
+ * typings
+ */
+ function transformVNodeArgs(transformer) {
+ vnodeArgsTransformer = transformer;
+ }
+ const createVNodeWithArgsTransform = (...args) => {
+ return _createVNode(...(vnodeArgsTransformer
+ ? vnodeArgsTransformer(args, currentRenderingInstance)
+ : args));
+ };
+ const InternalObjectKey = `__vInternal`;
+ const normalizeKey = ({ key }) => key != null ? key : null;
+ const normalizeRef = ({ ref }) => {
+ return (ref != null
+ ? isString(ref) || isRef(ref) || isFunction(ref)
+ ? { i: currentRenderingInstance, r: ref }
+ : ref
+ : null);
+ };
+ function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
+ const vnode = {
+ __v_isVNode: true,
+ __v_skip: true,
+ type,
+ props,
+ key: props && normalizeKey(props),
+ ref: props && normalizeRef(props),
+ scopeId: currentScopeId,
+ slotScopeIds: null,
+ children,
+ component: null,
+ suspense: null,
+ ssContent: null,
+ ssFallback: null,
+ dirs: null,
+ transition: null,
+ el: null,
+ anchor: null,
+ target: null,
+ targetAnchor: null,
+ staticCount: 0,
+ shapeFlag,
+ patchFlag,
+ dynamicProps,
+ dynamicChildren: null,
+ appContext: null
+ };
+ if (needFullChildrenNormalization) {
+ normalizeChildren(vnode, children);
+ // normalize suspense children
+ if (shapeFlag & 128 /* SUSPENSE */) {
+ type.normalize(vnode);
+ }
+ }
+ else if (children) {
+ // compiled element vnode - if children is passed, only possible types are
+ // string or Array.
+ vnode.shapeFlag |= isString(children)
+ ? 8 /* TEXT_CHILDREN */
+ : 16 /* ARRAY_CHILDREN */;
+ }
+ // validate key
+ if (vnode.key !== vnode.key) {
+ warn$1(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
+ }
+ // track vnode for block tree
+ if (isBlockTreeEnabled > 0 &&
+ // avoid a block node from tracking itself
+ !isBlockNode &&
+ // has current parent block
+ currentBlock &&
+ // presence of a patch flag indicates this node needs patching on updates.
+ // component nodes also should always be patched, because even if the
+ // component doesn't need to update, it needs to persist the instance on to
+ // the next vnode so that it can be properly unmounted later.
+ (vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
+ // the EVENTS flag is only for hydration and if it is the only flag, the
+ // vnode should not be considered dynamic due to handler caching.
+ vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) {
+ currentBlock.push(vnode);
+ }
+ return vnode;
+ }
+ const createVNode = (createVNodeWithArgsTransform );
+ function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
+ if (!type || type === NULL_DYNAMIC_COMPONENT) {
+ if (!type) {
+ warn$1(`Invalid vnode type when creating vnode: ${type}.`);
+ }
+ type = Comment;
+ }
+ if (isVNode(type)) {
+ // createVNode receiving an existing vnode. This happens in cases like
+ //
+ // #2078 make sure to merge refs during the clone instead of overwriting it
+ const cloned = cloneVNode(type, props, true /* mergeRef: true */);
+ if (children) {
+ normalizeChildren(cloned, children);
+ }
+ return cloned;
+ }
+ // class component normalization.
+ if (isClassComponent(type)) {
+ type = type.__vccOpts;
+ }
+ // class & style normalization.
+ if (props) {
+ // for reactive or proxy objects, we need to clone it to enable mutation.
+ props = guardReactiveProps(props);
+ let { class: klass, style } = props;
+ if (klass && !isString(klass)) {
+ props.class = normalizeClass(klass);
+ }
+ if (isObject(style)) {
+ // reactive state objects need to be cloned since they are likely to be
+ // mutated
+ if (isProxy(style) && !isArray(style)) {
+ style = extend({}, style);
+ }
+ props.style = normalizeStyle(style);
+ }
+ }
+ // encode the vnode type information into a bitmap
+ const shapeFlag = isString(type)
+ ? 1 /* ELEMENT */
+ : isSuspense(type)
+ ? 128 /* SUSPENSE */
+ : isTeleport(type)
+ ? 64 /* TELEPORT */
+ : isObject(type)
+ ? 4 /* STATEFUL_COMPONENT */
+ : isFunction(type)
+ ? 2 /* FUNCTIONAL_COMPONENT */
+ : 0;
+ if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
+ type = toRaw(type);
+ warn$1(`Vue received a Component which was made a reactive object. This can ` +
+ `lead to unnecessary performance overhead, and should be avoided by ` +
+ `marking the component with \`markRaw\` or using \`shallowRef\` ` +
+ `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
+ }
+ return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
+ }
+ function guardReactiveProps(props) {
+ if (!props)
+ return null;
+ return isProxy(props) || InternalObjectKey in props
+ ? extend({}, props)
+ : props;
+ }
+ function cloneVNode(vnode, extraProps, mergeRef = false) {
+ // This is intentionally NOT using spread or extend to avoid the runtime
+ // key enumeration cost.
+ const { props, ref, patchFlag, children } = vnode;
+ const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
+ const cloned = {
+ __v_isVNode: true,
+ __v_skip: true,
+ type: vnode.type,
+ props: mergedProps,
+ key: mergedProps && normalizeKey(mergedProps),
+ ref: extraProps && extraProps.ref
+ ? // #2078 in the case of
+ // if the vnode itself already has a ref, cloneVNode will need to merge
+ // the refs so the single vnode can be set on multiple refs
+ mergeRef && ref
+ ? isArray(ref)
+ ? ref.concat(normalizeRef(extraProps))
+ : [ref, normalizeRef(extraProps)]
+ : normalizeRef(extraProps)
+ : ref,
+ scopeId: vnode.scopeId,
+ slotScopeIds: vnode.slotScopeIds,
+ children: patchFlag === -1 /* HOISTED */ && isArray(children)
+ ? children.map(deepCloneVNode)
+ : children,
+ target: vnode.target,
+ targetAnchor: vnode.targetAnchor,
+ staticCount: vnode.staticCount,
+ shapeFlag: vnode.shapeFlag,
+ // if the vnode is cloned with extra props, we can no longer assume its
+ // existing patch flag to be reliable and need to add the FULL_PROPS flag.
+ // note: perserve flag for fragments since they use the flag for children
+ // fast paths only.
+ patchFlag: extraProps && vnode.type !== Fragment
+ ? patchFlag === -1 // hoisted node
+ ? 16 /* FULL_PROPS */
+ : patchFlag | 16 /* FULL_PROPS */
+ : patchFlag,
+ dynamicProps: vnode.dynamicProps,
+ dynamicChildren: vnode.dynamicChildren,
+ appContext: vnode.appContext,
+ dirs: vnode.dirs,
+ transition: vnode.transition,
+ // These should technically only be non-null on mounted VNodes. However,
+ // they *should* be copied for kept-alive vnodes. So we just always copy
+ // them since them being non-null during a mount doesn't affect the logic as
+ // they will simply be overwritten.
+ component: vnode.component,
+ suspense: vnode.suspense,
+ ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
+ ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
+ el: vnode.el,
+ anchor: vnode.anchor
+ };
+ return cloned;
+ }
+ /**
+ * Dev only, for HMR of hoisted vnodes reused in v-for
+ * https://github.com/vitejs/vite/issues/2022
+ */
+ function deepCloneVNode(vnode) {
+ const cloned = cloneVNode(vnode);
+ if (isArray(vnode.children)) {
+ cloned.children = vnode.children.map(deepCloneVNode);
+ }
+ return cloned;
+ }
+ /**
+ * @private
+ */
+ function createTextVNode(text = ' ', flag = 0) {
+ return createVNode(Text, null, text, flag);
+ }
+ /**
+ * @private
+ */
+ function createStaticVNode(content, numberOfNodes) {
+ // A static vnode can contain multiple stringified elements, and the number
+ // of elements is necessary for hydration.
+ const vnode = createVNode(Static, null, content);
+ vnode.staticCount = numberOfNodes;
+ return vnode;
+ }
+ /**
+ * @private
+ */
+ function createCommentVNode(text = '',
+ // when used as the v-else branch, the comment node must be created as a
+ // block to ensure correct updates.
+ asBlock = false) {
+ return asBlock
+ ? (openBlock(), createBlock(Comment, null, text))
+ : createVNode(Comment, null, text);
+ }
+ function normalizeVNode(child) {
+ if (child == null || typeof child === 'boolean') {
+ // empty placeholder
+ return createVNode(Comment);
+ }
+ else if (isArray(child)) {
+ // fragment
+ return createVNode(Fragment, null,
+ // #3666, avoid reference pollution when reusing vnode
+ child.slice());
+ }
+ else if (typeof child === 'object') {
+ // already vnode, this should be the most common since compiled templates
+ // always produce all-vnode children arrays
+ return cloneIfMounted(child);
+ }
+ else {
+ // strings and numbers
+ return createVNode(Text, null, String(child));
+ }
+ }
+ // optimized normalization for template-compiled render fns
+ function cloneIfMounted(child) {
+ return child.el === null || child.memo ? child : cloneVNode(child);
+ }
+ function normalizeChildren(vnode, children) {
+ let type = 0;
+ const { shapeFlag } = vnode;
+ if (children == null) {
+ children = null;
+ }
+ else if (isArray(children)) {
+ type = 16 /* ARRAY_CHILDREN */;
+ }
+ else if (typeof children === 'object') {
+ if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) {
+ // Normalize slot to plain children for plain element and Teleport
+ const slot = children.default;
+ if (slot) {
+ // _c marker is added by withCtx() indicating this is a compiled slot
+ slot._c && (slot._d = false);
+ normalizeChildren(vnode, slot());
+ slot._c && (slot._d = true);
+ }
+ return;
+ }
+ else {
+ type = 32 /* SLOTS_CHILDREN */;
+ const slotFlag = children._;
+ if (!slotFlag && !(InternalObjectKey in children)) {
+ children._ctx = currentRenderingInstance;
+ }
+ else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
+ // a child component receives forwarded slots from the parent.
+ // its slot type is determined by its parent's slot type.
+ if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
+ children._ = 1 /* STABLE */;
+ }
+ else {
+ children._ = 2 /* DYNAMIC */;
+ vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
+ }
+ }
+ }
+ }
+ else if (isFunction(children)) {
+ children = { default: children, _ctx: currentRenderingInstance };
+ type = 32 /* SLOTS_CHILDREN */;
+ }
+ else {
+ children = String(children);
+ // force teleport children to array so it can be moved around
+ if (shapeFlag & 64 /* TELEPORT */) {
+ type = 16 /* ARRAY_CHILDREN */;
+ children = [createTextVNode(children)];
+ }
+ else {
+ type = 8 /* TEXT_CHILDREN */;
+ }
+ }
+ vnode.children = children;
+ vnode.shapeFlag |= type;
+ }
+ function mergeProps(...args) {
+ const ret = {};
+ for (let i = 0; i < args.length; i++) {
+ const toMerge = args[i];
+ for (const key in toMerge) {
+ if (key === 'class') {
+ if (ret.class !== toMerge.class) {
+ ret.class = normalizeClass([ret.class, toMerge.class]);
+ }
+ }
+ else if (key === 'style') {
+ ret.style = normalizeStyle([ret.style, toMerge.style]);
+ }
+ else if (isOn(key)) {
+ const existing = ret[key];
+ const incoming = toMerge[key];
+ if (existing !== incoming) {
+ ret[key] = existing
+ ? [].concat(existing, incoming)
+ : incoming;
+ }
+ }
+ else if (key !== '') {
+ ret[key] = toMerge[key];
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Actual implementation
+ */
+ function renderList(source, renderItem, cache, index) {
+ let ret;
+ const cached = (cache && cache[index]);
+ if (isArray(source) || isString(source)) {
+ ret = new Array(source.length);
+ for (let i = 0, l = source.length; i < l; i++) {
+ ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
+ }
+ }
+ else if (typeof source === 'number') {
+ if (!Number.isInteger(source)) {
+ warn$1(`The v-for range expect an integer value but got ${source}.`);
+ return [];
+ }
+ ret = new Array(source);
+ for (let i = 0; i < source; i++) {
+ ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
+ }
+ }
+ else if (isObject(source)) {
+ if (source[Symbol.iterator]) {
+ ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
+ }
+ else {
+ const keys = Object.keys(source);
+ ret = new Array(keys.length);
+ for (let i = 0, l = keys.length; i < l; i++) {
+ const key = keys[i];
+ ret[i] = renderItem(source[key], key, i, cached && cached[i]);
+ }
+ }
+ }
+ else {
+ ret = [];
+ }
+ if (cache) {
+ cache[index] = ret;
+ }
+ return ret;
+ }
+
+ /**
+ * Compiler runtime helper for creating dynamic slots object
+ * @private
+ */
+ function createSlots(slots, dynamicSlots) {
+ for (let i = 0; i < dynamicSlots.length; i++) {
+ const slot = dynamicSlots[i];
+ // array of dynamic slot generated by
+ if (isArray(slot)) {
+ for (let j = 0; j < slot.length; j++) {
+ slots[slot[j].name] = slot[j].fn;
+ }
+ }
+ else if (slot) {
+ // conditional single slot generated by
+ slots[slot.name] = slot.fn;
+ }
+ }
+ return slots;
+ }
+
+ /**
+ * Compiler runtime helper for rendering ` `
+ * @private
+ */
+ function renderSlot(slots, name, props = {},
+ // this is not a user-facing function, so the fallback is always generated by
+ // the compiler and guaranteed to be a function returning an array
+ fallback, noSlotted) {
+ if (currentRenderingInstance.isCE) {
+ return createVNode('slot', name === 'default' ? null : { name }, fallback && fallback());
+ }
+ let slot = slots[name];
+ if (slot && slot.length > 1) {
+ warn$1(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
+ `function. You need to mark this component with $dynamic-slots in the ` +
+ `parent template.`);
+ slot = () => [];
+ }
+ // a compiled slot disables block tracking by default to avoid manual
+ // invocation interfering with template-based block tracking, but in
+ // `renderSlot` we can be sure that it's template-based so we can force
+ // enable it.
+ if (slot && slot._c) {
+ slot._d = false;
+ }
+ openBlock();
+ const validSlotContent = slot && ensureValidVNode(slot(props));
+ const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
+ ? 64 /* STABLE_FRAGMENT */
+ : -2 /* BAIL */);
+ if (!noSlotted && rendered.scopeId) {
+ rendered.slotScopeIds = [rendered.scopeId + '-s'];
+ }
+ if (slot && slot._c) {
+ slot._d = true;
+ }
+ return rendered;
+ }
+ function ensureValidVNode(vnodes) {
+ return vnodes.some(child => {
+ if (!isVNode(child))
+ return true;
+ if (child.type === Comment)
+ return false;
+ if (child.type === Fragment &&
+ !ensureValidVNode(child.children))
+ return false;
+ return true;
+ })
+ ? vnodes
+ : null;
+ }
+
+ /**
+ * For prefixing keys in v-on="obj" with "on"
+ * @private
+ */
+ function toHandlers(obj) {
+ const ret = {};
+ if (!isObject(obj)) {
+ warn$1(`v-on with no argument expects an object value.`);
+ return ret;
+ }
+ for (const key in obj) {
+ ret[toHandlerKey(key)] = obj[key];
+ }
+ return ret;
+ }
+
+ /**
+ * #2437 In Vue 3, functional components do not have a public instance proxy but
+ * they exist in the internal parent chain. For code that relies on traversing
+ * public $parent chains, skip functional ones and go to the parent instead.
+ */
+ const getPublicInstance = (i) => {
+ if (!i)
+ return null;
+ if (isStatefulComponent(i))
+ return getExposeProxy(i) || i.proxy;
+ return getPublicInstance(i.parent);
+ };
+ const publicPropertiesMap = extend(Object.create(null), {
+ $: i => i,
+ $el: i => i.vnode.el,
+ $data: i => i.data,
+ $props: i => (shallowReadonly(i.props) ),
+ $attrs: i => (shallowReadonly(i.attrs) ),
+ $slots: i => (shallowReadonly(i.slots) ),
+ $refs: i => (shallowReadonly(i.refs) ),
+ $parent: i => getPublicInstance(i.parent),
+ $root: i => getPublicInstance(i.root),
+ $emit: i => i.emit,
+ $options: i => (resolveMergedOptions(i) ),
+ $forceUpdate: i => () => queueJob(i.update),
+ $nextTick: i => nextTick.bind(i.proxy),
+ $watch: i => (instanceWatch.bind(i) )
+ });
+ const PublicInstanceProxyHandlers = {
+ get({ _: instance }, key) {
+ const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
+ // for internal formatters to know that this is a Vue instance
+ if (key === '__isVue') {
+ return true;
+ }
+ // prioritize