commit 1f37d21bf0f6cbba68e57b81628c70c713d74e29 Author: JianMiau Date: Sat May 28 13:52:14 2022 +0800 [add] first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..3dc5b08 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["johnsoncodehk.volar"] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..0217dde --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Vue 3 + Typescript + Vite + +1. npm install +2. npm run dev + +This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 ` + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..76eb881 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3138 @@ +{ + "name": "bj-casino-rank", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "bj-casino-rank", + "version": "0.0.0", + "dependencies": { + "@ant-design/icons-vue": "^6.1.0", + "@popperjs/core": "^2.11.5", + "axios": "^0.26.1", + "bootstrap": "^5.1.3", + "dayjs": "^1.11.2", + "element-plus": "^2.1.9", + "vue": "^3.2.25", + "vue-loading-overlay": "^5.0.3" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^2.3.0", + "typescript": "^4.5.4", + "vite": "^2.9.0", + "vue-tsc": "^0.29.8" + } + }, + "node_modules/@ant-design/colors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "dependencies": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.2.1.tgz", + "integrity": "sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==" + }, + "node_modules/@ant-design/icons-vue": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-6.1.0.tgz", + "integrity": "sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1" + }, + "peerDependencies": { + "vue": ">=3.0.3" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz", + "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz", + "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz", + "integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@emmetio/abbreviation": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.2.3.tgz", + "integrity": "sha512-87pltuCPt99aL+y9xS6GPZ+Wmmyhll2WXH73gG/xpGcQ84DRnptBsI2r0BeIQ0EB/SQTOe2ANPqFqj3Rj5FOGA==", + "dev": true, + "dependencies": { + "@emmetio/scanner": "^1.0.0" + } + }, + "node_modules/@emmetio/css-abbreviation": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.4.tgz", + "integrity": "sha512-qk9L60Y+uRtM5CPbB0y+QNl/1XKE09mSO+AhhSauIfr2YOx/ta3NJw2d8RtCFxgzHeRqFRr8jgyzThbu+MZ4Uw==", + "dev": true, + "dependencies": { + "@emmetio/scanner": "^1.0.0" + } + }, + "node_modules/@emmetio/scanner": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.0.tgz", + "integrity": "sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA==", + "dev": true + }, + "node_modules/@floating-ui/core": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.6.1.tgz", + "integrity": "sha512-Y30eVMcZva8o84c0HcXAtDO4BEzPJMvF6+B7x7urL2xbAqVsGJhojOyHLaoQHQYjb6OkqRq5kO+zeySycQwKqg==" + }, + "node_modules/@floating-ui/dom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.4.4.tgz", + "integrity": "sha512-0Ulu3B/dqQplUUSqnTx0foSrlYuMN+GTtlJWvNJwt6Fr7/PqmlR/Y08o6/+bxDWr6p3roBJRaQ51MDZsNmEhhw==", + "dependencies": { + "@floating-ui/core": "^0.6.1" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", + "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.6", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz", + "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz", + "integrity": "sha512-YNzBt8+jt6bSwpt7LP890U1UcTOIZZxfpE5WOJ638PNxSEKOqAi0+FSKS0nVeukfdZ0Ai/H7AFd6k3hayfGZqQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "vite": "^2.5.10", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/code-gen": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/code-gen/-/code-gen-0.29.8.tgz", + "integrity": "sha512-eohLLUqPChHRPDFT5gXn4V6pr/CeTri7Ou5GI26lUvBRRAbP8p+oYfQRcbMPGeKmVkYjfVj0chsxQGx6T8PQ4Q==", + "dev": true, + "dependencies": { + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8" + } + }, + "node_modules/@volar/html2pug": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/html2pug/-/html2pug-0.29.8.tgz", + "integrity": "sha512-bhSNXg8A2aD3w0B+CwmHjqCAaKtj5rORbE5C/q/UdGqptJbC6STCmi30KuRTdfPhR++Xb18Hauf3s/WCmtNAPA==", + "deprecated": "WARNING: This project has been renamed to @johnsoncodehk/html2pug. Install using @johnsoncodehk/html2pug instead.", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0", + "domhandler": "^4.2.2", + "htmlparser2": "^7.1.2", + "pug": "^3.0.2" + } + }, + "node_modules/@volar/shared": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/shared/-/shared-0.29.8.tgz", + "integrity": "sha512-Y1NN6irkIukD+T0wf4p/dHWYL90sacN2e2lYoDXxRlvoYxwANnHgw0J0Rcp+yw58ElWRScdG7/YntEIuZWeJsw==", + "dev": true, + "dependencies": { + "upath": "^2.0.1", + "vscode-jsonrpc": "^8.0.0-next.2", + "vscode-uri": "^3.0.2" + } + }, + "node_modules/@volar/source-map": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-0.29.8.tgz", + "integrity": "sha512-7w+UoYtnc6UQu30CgMVvx0YN4dzDgP4TIsSmUaW62AGmxU9Lxwp3Kkn/4N8efi91z8ma5Z78v/HddyJPwAC3LA==", + "dev": true, + "dependencies": { + "@volar/shared": "0.29.8" + } + }, + "node_modules/@volar/transforms": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/transforms/-/transforms-0.29.8.tgz", + "integrity": "sha512-o2hRa8CoDwYTO1Mu5KA47+1elUnYUjDaVhCvbyKlRfd8qpHea2llotArq7B6OORSL2M9DVs1IRJ5NGURBFeZ3Q==", + "dev": true, + "dependencies": { + "@volar/shared": "0.29.8", + "vscode-languageserver": "^8.0.0-next.2" + } + }, + "node_modules/@volar/vue-code-gen": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/vue-code-gen/-/vue-code-gen-0.29.8.tgz", + "integrity": "sha512-E1e7P2oktNC/DzgDBditfla4s8+HlUlluZ+BtcLvEdbkl3QEjujkB0x1wxguWzXmpWgLIDPtrS3Jzll5cCOkTg==", + "dev": true, + "dependencies": { + "@volar/code-gen": "0.29.8", + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8", + "@vue/compiler-core": "^3.2.21", + "@vue/compiler-dom": "^3.2.21", + "@vue/shared": "^3.2.21", + "upath": "^2.0.1" + } + }, + "node_modules/@vscode/emmet-helper": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.8.4.tgz", + "integrity": "sha512-lUki5QLS47bz/U8IlG9VQ+1lfxMtxMZENmU5nu4Z71eOD5j9FK0SmYGL5NiVJg9WBWeAU0VxRADMY2Qpq7BfVg==", + "dev": true, + "dependencies": { + "emmet": "^2.3.0", + "jsonc-parser": "^2.3.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.15.1", + "vscode-nls": "^5.0.0", + "vscode-uri": "^2.1.2" + } + }, + "node_modules/@vscode/emmet-helper/node_modules/vscode-uri": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", + "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==", + "dev": true + }, + "node_modules/@vue/compiler-core": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.31.tgz", + "integrity": "sha512-aKno00qoA4o+V/kR6i/pE+aP+esng5siNAVQ422TkBNM6qA4veXiZbSe8OTXHXquEi/f6Akc+nLfB4JGfe4/WQ==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.31", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.31.tgz", + "integrity": "sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==", + "dependencies": { + "@vue/compiler-core": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.31.tgz", + "integrity": "sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.31", + "@vue/compiler-dom": "3.2.31", + "@vue/compiler-ssr": "3.2.31", + "@vue/reactivity-transform": "3.2.31", + "@vue/shared": "3.2.31", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7", + "postcss": "^8.1.10", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.31.tgz", + "integrity": "sha512-mjN0rqig+A8TVDnsGPYJM5dpbjlXeHUm2oZHZwGyMYiGT/F4fhJf/cXy8QpjnLQK4Y9Et4GWzHn9PS8AHUnSkw==", + "dependencies": { + "@vue/compiler-dom": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.31.tgz", + "integrity": "sha512-HVr0l211gbhpEKYr2hYe7hRsV91uIVGFYNHj73njbARVGHQvIojkImKMaZNDdoDZOIkMsBc9a1sMqR+WZwfSCw==", + "dependencies": { + "@vue/shared": "3.2.31" + } + }, + "node_modules/@vue/reactivity-transform": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.31.tgz", + "integrity": "sha512-uS4l4z/W7wXdI+Va5pgVxBJ345wyGFKvpPYtdSgvfJfX/x2Ymm6ophQlXXB6acqGHtXuBqNyyO3zVp9b1r0MOA==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.31", + "@vue/shared": "3.2.31", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.31.tgz", + "integrity": "sha512-Kcog5XmSY7VHFEMuk4+Gap8gUssYMZ2+w+cmGI6OpZWYOEIcbE0TPzzPHi+8XTzAgx1w/ZxDFcXhZeXN5eKWsA==", + "dependencies": { + "@vue/reactivity": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.31.tgz", + "integrity": "sha512-N+o0sICVLScUjfLG7u9u5XCjvmsexAiPt17GNnaWHJUfsKed5e85/A3SWgKxzlxx2SW/Hw7RQxzxbXez9PtY3g==", + "dependencies": { + "@vue/runtime-core": "3.2.31", + "@vue/shared": "3.2.31", + "csstype": "^2.6.8" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.31.tgz", + "integrity": "sha512-8CN3Zj2HyR2LQQBHZ61HexF5NReqngLT3oahyiVRfSSvak+oAvVmu8iNLSu6XR77Ili2AOpnAt1y8ywjjqtmkg==", + "dependencies": { + "@vue/compiler-ssr": "3.2.31", + "@vue/shared": "3.2.31" + }, + "peerDependencies": { + "vue": "3.2.31" + } + }, + "node_modules/@vue/shared": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.31.tgz", + "integrity": "sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==" + }, + "node_modules/@vueuse/core": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-8.2.6.tgz", + "integrity": "sha512-fzlpM3B5oVe+UhCT1mXlhG1Zxdq2lq1Z2AvddSB8+RxrsSFzII7DKfsQEz8Vop7Lzc++4m8drTNbhPovYoFqHw==", + "dependencies": { + "@vueuse/metadata": "8.2.6", + "@vueuse/shared": "8.2.6", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.1.0", + "vue": "^2.6.0 || ^3.2.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/@vueuse/core/node_modules/@vueuse/shared": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-8.2.6.tgz", + "integrity": "sha512-J/W4CMfdL8TahELuSOgtfVO4eQXTjhigp7dVWIBsLUVFCeY9d49gvHUcQN3y5xYLZ6iNP57TjTQjMMT/zhklkw==", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.1.0", + "vue": "^2.6.0 || ^3.2.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz", + "integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-8.2.6.tgz", + "integrity": "sha512-OBKtafCt+4RcEJlYDCjp1vl65pBCL2g4TmipEtdZ8/qphKlW6nakJbkY7XRN5grPmjqU99/ahJGtyGk5NHS2hw==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "node_modules/assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==", + "dev": true + }, + "node_modules/async-validator": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz", + "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==" + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bootstrap": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", + "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + }, + "peerDependencies": { + "@popperjs/core": "^2.10.2" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "dev": true, + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/csstype": { + "version": "2.6.20", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz", + "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==" + }, + "node_modules/dayjs": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", + "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=", + "dev": true + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/element-plus": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.1.9.tgz", + "integrity": "sha512-6mWqS3YrmJPnouWP4otzL8+MehfOnDFqDbcIdnmC07p+Z0JkWe/CVKc4Wky8AYC8nyDMUQyiZYvooCbqGuM7pg==", + "dependencies": { + "@ctrl/tinycolor": "^3.4.0", + "@element-plus/icons-vue": "^1.1.4", + "@floating-ui/dom": "^0.4.2", + "@popperjs/core": "^2.11.4", + "@types/lodash": "^4.14.181", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^8.2.4", + "async-validator": "^4.0.7", + "dayjs": "^1.11.0", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.1.2" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/emmet": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.3.6.tgz", + "integrity": "sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==", + "dev": true, + "dependencies": { + "@emmetio/abbreviation": "^2.2.3", + "@emmetio/css-abbreviation": "^2.1.4" + } + }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.34.tgz", + "integrity": "sha512-QIWdPT/gFF6hCaf4m7kP0cJ+JIuFkdHibI7vVFvu3eJS1HpVmYHWDulyN5WXwbRA0SX/7ZDaJ/1DH8SdY9xOJg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "esbuild-android-64": "0.14.34", + "esbuild-android-arm64": "0.14.34", + "esbuild-darwin-64": "0.14.34", + "esbuild-darwin-arm64": "0.14.34", + "esbuild-freebsd-64": "0.14.34", + "esbuild-freebsd-arm64": "0.14.34", + "esbuild-linux-32": "0.14.34", + "esbuild-linux-64": "0.14.34", + "esbuild-linux-arm": "0.14.34", + "esbuild-linux-arm64": "0.14.34", + "esbuild-linux-mips64le": "0.14.34", + "esbuild-linux-ppc64le": "0.14.34", + "esbuild-linux-riscv64": "0.14.34", + "esbuild-linux-s390x": "0.14.34", + "esbuild-netbsd-64": "0.14.34", + "esbuild-openbsd-64": "0.14.34", + "esbuild-sunos-64": "0.14.34", + "esbuild-windows-32": "0.14.34", + "esbuild-windows-64": "0.14.34", + "esbuild-windows-arm64": "0.14.34" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.34.tgz", + "integrity": "sha512-XfxcfJqmMYsT/LXqrptzFxmaR3GWzXHDLdFNIhm6S00zPaQF1TBBWm+9t0RZ6LRR7iwH57DPjaOeW20vMqI4Yw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.34.tgz", + "integrity": "sha512-T02+NXTmSRL1Mc6puz+R9CB54rSPICkXKq6+tw8B6vxZFnCPzbJxgwIX4kcluz9p8nYBjF3+lSilTGWb7+Xgew==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.34.tgz", + "integrity": "sha512-pLRip2Bh4Ng7Bf6AMgCrSp3pPe/qZyf11h5Qo2mOfJqLWzSVjxrXW+CFRJfrOVP7TCnh/gmZSM2AFdCPB72vtw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.34.tgz", + "integrity": "sha512-vpidSJEBxx6lf1NWgXC+DCmGqesJuZ5Y8aQVVsaoO4i8tRXbXb0whChRvop/zd3nfNM4dIl5EXAky0knRX5I6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.34.tgz", + "integrity": "sha512-m0HBjePhe0hAQJgtMRMNV9kMgIyV4/qSnzPx42kRMQBcPhgjAq1JRu4Il26czC+9FgpMbFkUktb07f/Lwnc6CA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.34.tgz", + "integrity": "sha512-cpRc2B94L1KvMPPYB4D6G39jLqpKlD3noAMY4/e86iXXXkhUYJJEtTuyNFTa9JRpWM0xCAp4mxjHjoIiLuoCLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.34.tgz", + "integrity": "sha512-8nQaEaoW7MH/K/RlozJa+lE1ejHIr8fuPIHhc513UebRav7HtXgQvxHQ6VZRUkWtep23M6dd7UqhwO1tMOfzQQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.34.tgz", + "integrity": "sha512-Y3of4qQoLLlAgf042MlrY1P+7PnN9zWj8nVtw9XQG5hcLOZLz7IKpU35oeu7n4wvyaZHwvQqDJ93gRLqdJekcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.34.tgz", + "integrity": "sha512-9lpq1NcJqssAF7alCO6zL3gvBVVt/lKw4oetUM7OgNnRX0OWpB+ZIO9FwCrSj/dMdmgDhPLf+119zB8QxSMmAg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.34.tgz", + "integrity": "sha512-IlWaGtj9ir7+Nrume1DGcyzBDlK8GcnJq0ANKwcI9pVw8tqr+6GD0eqyF9SF1mR8UmAp+odrx1H5NdR2cHdFHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.34.tgz", + "integrity": "sha512-k3or+01Rska1AjUyNjA4buEwB51eyN/xPQAoOx1CjzAQC3l8rpjUDw55kXyL63O/1MUi4ISvtNtl8gLwdyEcxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.34.tgz", + "integrity": "sha512-+qxb8M9FfM2CJaVU7GgYpJOHM1ngQOx+/VrtBjb4C8oVqaPcESCeg2anjl+HRZy8VpYc71q/iBYausPPbJ+Keg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.34.tgz", + "integrity": "sha512-Y717ltBdQ5j5sZIHdy1DV9kieo0wMip0dCmVSTceowCPYSn1Cg33Kd6981+F/3b9FDMzNWldZFOBRILViENZSA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.34.tgz", + "integrity": "sha512-bDDgYO4LhL4+zPs+WcBkXph+AQoPcQRTv18FzZS0WhjfH8TZx2QqlVPGhmhZ6WidrY+jKthUqO6UhGyIb4MpmA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.34.tgz", + "integrity": "sha512-cfaFGXdRt0+vHsjNPyF0POM4BVSHPSbhLPe8mppDc7GDDxjIl08mV1Zou14oDWMp/XZMjYN1kWYRSfftiD0vvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.34.tgz", + "integrity": "sha512-vmy9DxXVnRiI14s8GKuYBtess+EVcDALkbpTqd5jw4XITutIzyB7n4x0Tj5utAkKsgZJB22lLWGekr0ABnSLow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.34.tgz", + "integrity": "sha512-eNPVatNET1F7tRMhii7goL/eptfxc0ALRjrj9SPFNqp0zmxrehBFD6BaP3R4LjMn6DbMO0jOAnTLFKr8NqcJAA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.34.tgz", + "integrity": "sha512-EFhpXyHEcnqWYe2rAHFd8dRw8wkrd9U+9oqcyoEL84GbanAYjiiIjBZsnR8kl0sCQ5w6bLpk7vCEIA2VS32Vcg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.34.tgz", + "integrity": "sha512-a8fbl8Ky7PxNEjf1aJmtxdDZj32/hC7S1OcA2ckEpCJRTjiKslI9vAdPpSjrKIWhws4Galpaawy0nB7fjHYf5Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.34.tgz", + "integrity": "sha512-EYvmKbSa2B3sPnpC28UEu9jBK5atGV4BaVRE7CYGUci2Hlz4AvtV/LML+TcDMT6gBgibnN2gcltWclab3UutMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=", + "dev": true + }, + "node_modules/jsonc-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", + "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", + "dev": true + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "dev": true, + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash-unified": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.2.tgz", + "integrity": "sha512-OGbEy+1P+UT26CYi4opY4gebD8cWRDxAT6MAObIVQMiqYdxZr1g3QHWCToVsm31x2NkLS4K3+MC2qInaRMa39g==", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/lru-cache": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.0.tgz", + "integrity": "sha512-AmXqneQZL3KZMIgBpaPTeI6pfwh+xQ2vutMsyqOu1TBdEXFZgpG/80wuJ531w2ZN7TI0/oc8CPxzh/DKQudZqg==", + "deprecated": "Please update to latest patch version to fix memory leak https://github.com/isaacs/node-lru-cache/issues/227", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/nanoid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-wheel-es": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.1.2.tgz", + "integrity": "sha512-scX83plWJXYH1J4+BhAuIHadROzxX0UBF3+HuZNY2Ks8BciE7tSTQ+5JhTsvzjaO0/EJdm4JBGrfObKxFf3Png==" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/postcss": { + "version": "8.4.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz", + "integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.1", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "dev": true, + "dependencies": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dev": true, + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "dev": true, + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==", + "dev": true + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dev": true, + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dev": true, + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dev": true, + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dev": true, + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "dev": true + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dev": true, + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "dev": true + }, + "node_modules/request-light": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.5.7.tgz", + "integrity": "sha512-i/wKzvcx7Er8tZnvqSxWuNO5ZGggu2UgZAqj/RyZ0si7lBTXL7kZiI/dWxzxnQjaY7s5HEy1qK21Do4Ncr6cVw==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.70.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", + "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/semver": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz", + "integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.4.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=", + "dev": true + }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/vite": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.1.tgz", + "integrity": "sha512-vSlsSdOYGcYEJfkQ/NeLXgnRv5zZfpAsdztkIrs7AZHV8RCMZQkwjo4DS5BnrYTqoWqLoUe1Cah4aVO4oNNqCQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.14.27", + "postcss": "^8.4.12", + "resolve": "^1.22.0", + "rollup": "^2.59.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": ">=12.2.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "less": "*", + "sass": "*", + "stylus": "*" + }, + "peerDependenciesMeta": { + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vscode-css-languageservice": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-5.4.1.tgz", + "integrity": "sha512-W7D3GKFXf97ReAaU4EZ2nxVO1kQhztbycJgc1b/Ipr0h8zYWr88BADmrXu02z+lsCS84D7Sr4hoUzDKeaFn2Kg==", + "dev": true, + "dependencies": { + "vscode-languageserver-textdocument": "^1.0.4", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.3" + } + }, + "node_modules/vscode-html-languageservice": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-4.2.4.tgz", + "integrity": "sha512-1HqvXKOq9WlZyW4HTD+0XzrjZoZ/YFrgQY2PZqktbRloHXVAUKm6+cAcvZi4YqKPVn05/CK7do+KBHfuSaEdbg==", + "dev": true, + "dependencies": { + "vscode-languageserver-textdocument": "^1.0.4", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.3" + } + }, + "node_modules/vscode-json-languageservice": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz", + "integrity": "sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.0.0", + "vscode-languageserver-textdocument": "^1.0.3", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.3" + } + }, + "node_modules/vscode-json-languageservice/node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + }, + "node_modules/vscode-jsonrpc": { + "version": "8.0.0-next.7", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.0-next.7.tgz", + "integrity": "sha512-JX/F31LEsims0dAlOTKFE4E+AJMiJvdRSRViifFJSqSN7EzeYyWlfuDchF7g91oRNPZOIWfibTkDf3/UMsQGzQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "8.0.0-next.10", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.0.0-next.10.tgz", + "integrity": "sha512-sdjldl9ipuBSWVw5ENVMRcOVQwF0o+J6+lNA7FrB8MiLmzflnfjRoJMqA5tCEY8S/J/+P56ZR/dqiQnRYg5m8w==", + "dev": true, + "dependencies": { + "vscode-languageserver-protocol": "3.17.0-next.16" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.0-next.16", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.16.tgz", + "integrity": "sha512-tx4DnXw9u3N7vw+bx6n2NKp6FoxoNwiP/biH83AS30I2AnTGyLd7afSeH6Oewn2E8jvB7K15bs12sMppkKOVeQ==", + "dev": true, + "dependencies": { + "vscode-jsonrpc": "8.0.0-next.7", + "vscode-languageserver-types": "3.17.0-next.9" + } + }, + "node_modules/vscode-languageserver-protocol/node_modules/vscode-languageserver-types": { + "version": "3.17.0-next.9", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.9.tgz", + "integrity": "sha512-9/PeDNPYduaoXRUzYpqmu4ZV9L01HGo0wH9FUt+sSHR7IXwA7xoXBfNUlv8gB9H0D2WwEmMomSy1NmhjKQyn3A==", + "dev": true + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz", + "integrity": "sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ==", + "dev": true + }, + "node_modules/vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==", + "dev": true + }, + "node_modules/vscode-nls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.0.0.tgz", + "integrity": "sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==", + "dev": true + }, + "node_modules/vscode-pug-languageservice": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vscode-pug-languageservice/-/vscode-pug-languageservice-0.29.8.tgz", + "integrity": "sha512-QHYAzDSJLg7GOLxCZ12qsM0dAM0dPeMSS1t4kKfzLsfpErmZpFzkAIXbidVrNMdMffGZMtTuIlcpEyWHbx96Iw==", + "deprecated": "WARNING: This project has been renamed to @volar/pug-language-service. Install using @volar/pug-language-service instead.", + "dev": true, + "dependencies": { + "@volar/code-gen": "0.29.8", + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8", + "@volar/transforms": "0.29.8", + "pug-lexer": "^5.0.1", + "pug-parser": "^6.0.0", + "vscode-languageserver": "^8.0.0-next.2" + } + }, + "node_modules/vscode-typescript-languageservice": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vscode-typescript-languageservice/-/vscode-typescript-languageservice-0.29.8.tgz", + "integrity": "sha512-eecDqHk4WjEvy6VHQ6teHczppQ9yJO2wExCy7yu7WiFj35qbw0h4G6Erv46MvP3ClL8FggFzD7s1qM6vdqJUfw==", + "deprecated": "WARNING: This project has been renamed to @volar/typescript-language-service. Install using @volar/typescript-language-service instead.", + "dev": true, + "dependencies": { + "@volar/shared": "0.29.8", + "semver": "^7.3.5", + "upath": "^2.0.1", + "vscode-languageserver": "^8.0.0-next.2", + "vscode-languageserver-textdocument": "^1.0.1" + } + }, + "node_modules/vscode-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.3.tgz", + "integrity": "sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==", + "dev": true + }, + "node_modules/vscode-vue-languageservice": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vscode-vue-languageservice/-/vscode-vue-languageservice-0.29.8.tgz", + "integrity": "sha512-qSJdvW5ttyGUB/8uWDKgo8vnIoFnXYlBP4Z/cn54btsRn6ZMw7IJGJU1381e7p/yGvMTLeGbugD53SghbnSa6g==", + "deprecated": "WARNING: This project has been renamed to @volar/vue-language-service. Install using @volar/vue-language-service instead.", + "dev": true, + "dependencies": { + "@volar/code-gen": "0.29.8", + "@volar/html2pug": "0.29.8", + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8", + "@volar/transforms": "0.29.8", + "@volar/vue-code-gen": "0.29.8", + "@vscode/emmet-helper": "^2.8.0", + "@vue/reactivity": "^3.2.21", + "@vue/shared": "^3.2.21", + "request-light": "^0.5.4", + "upath": "^2.0.1", + "vscode-css-languageservice": "^5.1.7", + "vscode-html-languageservice": "^4.1.0", + "vscode-json-languageservice": "^4.1.8", + "vscode-languageserver": "^8.0.0-next.2", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-pug-languageservice": "0.29.8", + "vscode-typescript-languageservice": "0.29.8" + } + }, + "node_modules/vue": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.31.tgz", + "integrity": "sha512-odT3W2tcffTiQCy57nOT93INw1auq5lYLLYtWpPYQQYQOOdHiqFct9Xhna6GJ+pJQaF67yZABraH47oywkJgFw==", + "dependencies": { + "@vue/compiler-dom": "3.2.31", + "@vue/compiler-sfc": "3.2.31", + "@vue/runtime-dom": "3.2.31", + "@vue/server-renderer": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "node_modules/vue-loading-overlay": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-5.0.3.tgz", + "integrity": "sha512-6JWZalwlHF4do3HXsFZGt6PcWYseAI5FuNKpveEkljkzqskDWRr7rYmYHVx2kKu4qIvK0vLpL25T/hpFMNoevQ==", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-tsc": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.29.8.tgz", + "integrity": "sha512-pT0wLRjvRuSmB+J4WJT6uuV9mO0KtSSXEAtaVXZQzyk5+DJdbLIQTbRce/TXSkfqt1l1WogO78RjtOJFiMCgfQ==", + "dev": true, + "dependencies": { + "@volar/shared": "0.29.8", + "vscode-vue-languageservice": "0.29.8" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + } + }, + "dependencies": { + "@ant-design/colors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "requires": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "@ant-design/icons-svg": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.2.1.tgz", + "integrity": "sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==" + }, + "@ant-design/icons-vue": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-6.1.0.tgz", + "integrity": "sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==", + "requires": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/parser": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz", + "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==" + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@ctrl/tinycolor": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz", + "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==" + }, + "@element-plus/icons-vue": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz", + "integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==", + "requires": {} + }, + "@emmetio/abbreviation": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.2.3.tgz", + "integrity": "sha512-87pltuCPt99aL+y9xS6GPZ+Wmmyhll2WXH73gG/xpGcQ84DRnptBsI2r0BeIQ0EB/SQTOe2ANPqFqj3Rj5FOGA==", + "dev": true, + "requires": { + "@emmetio/scanner": "^1.0.0" + } + }, + "@emmetio/css-abbreviation": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.4.tgz", + "integrity": "sha512-qk9L60Y+uRtM5CPbB0y+QNl/1XKE09mSO+AhhSauIfr2YOx/ta3NJw2d8RtCFxgzHeRqFRr8jgyzThbu+MZ4Uw==", + "dev": true, + "requires": { + "@emmetio/scanner": "^1.0.0" + } + }, + "@emmetio/scanner": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.0.tgz", + "integrity": "sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA==", + "dev": true + }, + "@floating-ui/core": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.6.1.tgz", + "integrity": "sha512-Y30eVMcZva8o84c0HcXAtDO4BEzPJMvF6+B7x7urL2xbAqVsGJhojOyHLaoQHQYjb6OkqRq5kO+zeySycQwKqg==" + }, + "@floating-ui/dom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.4.4.tgz", + "integrity": "sha512-0Ulu3B/dqQplUUSqnTx0foSrlYuMN+GTtlJWvNJwt6Fr7/PqmlR/Y08o6/+bxDWr6p3roBJRaQ51MDZsNmEhhw==", + "requires": { + "@floating-ui/core": "^0.6.1" + } + }, + "@popperjs/core": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", + "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==" + }, + "@types/lodash": { + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" + }, + "@types/lodash-es": { + "version": "4.17.6", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz", + "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==", + "requires": { + "@types/lodash": "*" + } + }, + "@vitejs/plugin-vue": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz", + "integrity": "sha512-YNzBt8+jt6bSwpt7LP890U1UcTOIZZxfpE5WOJ638PNxSEKOqAi0+FSKS0nVeukfdZ0Ai/H7AFd6k3hayfGZqQ==", + "dev": true, + "requires": {} + }, + "@volar/code-gen": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/code-gen/-/code-gen-0.29.8.tgz", + "integrity": "sha512-eohLLUqPChHRPDFT5gXn4V6pr/CeTri7Ou5GI26lUvBRRAbP8p+oYfQRcbMPGeKmVkYjfVj0chsxQGx6T8PQ4Q==", + "dev": true, + "requires": { + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8" + } + }, + "@volar/html2pug": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/html2pug/-/html2pug-0.29.8.tgz", + "integrity": "sha512-bhSNXg8A2aD3w0B+CwmHjqCAaKtj5rORbE5C/q/UdGqptJbC6STCmi30KuRTdfPhR++Xb18Hauf3s/WCmtNAPA==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0", + "domhandler": "^4.2.2", + "htmlparser2": "^7.1.2", + "pug": "^3.0.2" + } + }, + "@volar/shared": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/shared/-/shared-0.29.8.tgz", + "integrity": "sha512-Y1NN6irkIukD+T0wf4p/dHWYL90sacN2e2lYoDXxRlvoYxwANnHgw0J0Rcp+yw58ElWRScdG7/YntEIuZWeJsw==", + "dev": true, + "requires": { + "upath": "^2.0.1", + "vscode-jsonrpc": "^8.0.0-next.2", + "vscode-uri": "^3.0.2" + } + }, + "@volar/source-map": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-0.29.8.tgz", + "integrity": "sha512-7w+UoYtnc6UQu30CgMVvx0YN4dzDgP4TIsSmUaW62AGmxU9Lxwp3Kkn/4N8efi91z8ma5Z78v/HddyJPwAC3LA==", + "dev": true, + "requires": { + "@volar/shared": "0.29.8" + } + }, + "@volar/transforms": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/transforms/-/transforms-0.29.8.tgz", + "integrity": "sha512-o2hRa8CoDwYTO1Mu5KA47+1elUnYUjDaVhCvbyKlRfd8qpHea2llotArq7B6OORSL2M9DVs1IRJ5NGURBFeZ3Q==", + "dev": true, + "requires": { + "@volar/shared": "0.29.8", + "vscode-languageserver": "^8.0.0-next.2" + } + }, + "@volar/vue-code-gen": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/@volar/vue-code-gen/-/vue-code-gen-0.29.8.tgz", + "integrity": "sha512-E1e7P2oktNC/DzgDBditfla4s8+HlUlluZ+BtcLvEdbkl3QEjujkB0x1wxguWzXmpWgLIDPtrS3Jzll5cCOkTg==", + "dev": true, + "requires": { + "@volar/code-gen": "0.29.8", + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8", + "@vue/compiler-core": "^3.2.21", + "@vue/compiler-dom": "^3.2.21", + "@vue/shared": "^3.2.21", + "upath": "^2.0.1" + } + }, + "@vscode/emmet-helper": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.8.4.tgz", + "integrity": "sha512-lUki5QLS47bz/U8IlG9VQ+1lfxMtxMZENmU5nu4Z71eOD5j9FK0SmYGL5NiVJg9WBWeAU0VxRADMY2Qpq7BfVg==", + "dev": true, + "requires": { + "emmet": "^2.3.0", + "jsonc-parser": "^2.3.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.15.1", + "vscode-nls": "^5.0.0", + "vscode-uri": "^2.1.2" + }, + "dependencies": { + "vscode-uri": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", + "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==", + "dev": true + } + } + }, + "@vue/compiler-core": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.31.tgz", + "integrity": "sha512-aKno00qoA4o+V/kR6i/pE+aP+esng5siNAVQ422TkBNM6qA4veXiZbSe8OTXHXquEi/f6Akc+nLfB4JGfe4/WQ==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.31", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-dom": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.31.tgz", + "integrity": "sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==", + "requires": { + "@vue/compiler-core": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "@vue/compiler-sfc": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.31.tgz", + "integrity": "sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.31", + "@vue/compiler-dom": "3.2.31", + "@vue/compiler-ssr": "3.2.31", + "@vue/reactivity-transform": "3.2.31", + "@vue/shared": "3.2.31", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7", + "postcss": "^8.1.10", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-ssr": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.31.tgz", + "integrity": "sha512-mjN0rqig+A8TVDnsGPYJM5dpbjlXeHUm2oZHZwGyMYiGT/F4fhJf/cXy8QpjnLQK4Y9Et4GWzHn9PS8AHUnSkw==", + "requires": { + "@vue/compiler-dom": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "@vue/reactivity": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.31.tgz", + "integrity": "sha512-HVr0l211gbhpEKYr2hYe7hRsV91uIVGFYNHj73njbARVGHQvIojkImKMaZNDdoDZOIkMsBc9a1sMqR+WZwfSCw==", + "requires": { + "@vue/shared": "3.2.31" + } + }, + "@vue/reactivity-transform": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.31.tgz", + "integrity": "sha512-uS4l4z/W7wXdI+Va5pgVxBJ345wyGFKvpPYtdSgvfJfX/x2Ymm6ophQlXXB6acqGHtXuBqNyyO3zVp9b1r0MOA==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.31", + "@vue/shared": "3.2.31", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "@vue/runtime-core": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.31.tgz", + "integrity": "sha512-Kcog5XmSY7VHFEMuk4+Gap8gUssYMZ2+w+cmGI6OpZWYOEIcbE0TPzzPHi+8XTzAgx1w/ZxDFcXhZeXN5eKWsA==", + "requires": { + "@vue/reactivity": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "@vue/runtime-dom": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.31.tgz", + "integrity": "sha512-N+o0sICVLScUjfLG7u9u5XCjvmsexAiPt17GNnaWHJUfsKed5e85/A3SWgKxzlxx2SW/Hw7RQxzxbXez9PtY3g==", + "requires": { + "@vue/runtime-core": "3.2.31", + "@vue/shared": "3.2.31", + "csstype": "^2.6.8" + } + }, + "@vue/server-renderer": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.31.tgz", + "integrity": "sha512-8CN3Zj2HyR2LQQBHZ61HexF5NReqngLT3oahyiVRfSSvak+oAvVmu8iNLSu6XR77Ili2AOpnAt1y8ywjjqtmkg==", + "requires": { + "@vue/compiler-ssr": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "@vue/shared": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.31.tgz", + "integrity": "sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==" + }, + "@vueuse/core": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-8.2.6.tgz", + "integrity": "sha512-fzlpM3B5oVe+UhCT1mXlhG1Zxdq2lq1Z2AvddSB8+RxrsSFzII7DKfsQEz8Vop7Lzc++4m8drTNbhPovYoFqHw==", + "requires": { + "@vueuse/metadata": "8.2.6", + "@vueuse/shared": "8.2.6", + "vue-demi": "*" + }, + "dependencies": { + "@vueuse/shared": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-8.2.6.tgz", + "integrity": "sha512-J/W4CMfdL8TahELuSOgtfVO4eQXTjhigp7dVWIBsLUVFCeY9d49gvHUcQN3y5xYLZ6iNP57TjTQjMMT/zhklkw==", + "requires": { + "vue-demi": "*" + } + }, + "vue-demi": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz", + "integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==", + "requires": {} + } + } + }, + "@vueuse/metadata": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-8.2.6.tgz", + "integrity": "sha512-OBKtafCt+4RcEJlYDCjp1vl65pBCL2g4TmipEtdZ8/qphKlW6nakJbkY7XRN5grPmjqU99/ahJGtyGk5NHS2hw==" + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==", + "dev": true + }, + "async-validator": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz", + "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==" + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6" + } + }, + "bootstrap": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", + "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", + "requires": {} + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "dev": true, + "requires": { + "is-regex": "^1.0.3" + } + }, + "constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dev": true, + "requires": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "csstype": { + "version": "2.6.20", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz", + "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==" + }, + "dayjs": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", + "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=", + "dev": true + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "dependencies": { + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "element-plus": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.1.9.tgz", + "integrity": "sha512-6mWqS3YrmJPnouWP4otzL8+MehfOnDFqDbcIdnmC07p+Z0JkWe/CVKc4Wky8AYC8nyDMUQyiZYvooCbqGuM7pg==", + "requires": { + "@ctrl/tinycolor": "^3.4.0", + "@element-plus/icons-vue": "^1.1.4", + "@floating-ui/dom": "^0.4.2", + "@popperjs/core": "^2.11.4", + "@types/lodash": "^4.14.181", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^8.2.4", + "async-validator": "^4.0.7", + "dayjs": "^1.11.0", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.1.2" + } + }, + "emmet": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.3.6.tgz", + "integrity": "sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==", + "dev": true, + "requires": { + "@emmetio/abbreviation": "^2.2.3", + "@emmetio/css-abbreviation": "^2.1.4" + } + }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, + "esbuild": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.34.tgz", + "integrity": "sha512-QIWdPT/gFF6hCaf4m7kP0cJ+JIuFkdHibI7vVFvu3eJS1HpVmYHWDulyN5WXwbRA0SX/7ZDaJ/1DH8SdY9xOJg==", + "dev": true, + "requires": { + "esbuild-android-64": "0.14.34", + "esbuild-android-arm64": "0.14.34", + "esbuild-darwin-64": "0.14.34", + "esbuild-darwin-arm64": "0.14.34", + "esbuild-freebsd-64": "0.14.34", + "esbuild-freebsd-arm64": "0.14.34", + "esbuild-linux-32": "0.14.34", + "esbuild-linux-64": "0.14.34", + "esbuild-linux-arm": "0.14.34", + "esbuild-linux-arm64": "0.14.34", + "esbuild-linux-mips64le": "0.14.34", + "esbuild-linux-ppc64le": "0.14.34", + "esbuild-linux-riscv64": "0.14.34", + "esbuild-linux-s390x": "0.14.34", + "esbuild-netbsd-64": "0.14.34", + "esbuild-openbsd-64": "0.14.34", + "esbuild-sunos-64": "0.14.34", + "esbuild-windows-32": "0.14.34", + "esbuild-windows-64": "0.14.34", + "esbuild-windows-arm64": "0.14.34" + } + }, + "esbuild-android-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.34.tgz", + "integrity": "sha512-XfxcfJqmMYsT/LXqrptzFxmaR3GWzXHDLdFNIhm6S00zPaQF1TBBWm+9t0RZ6LRR7iwH57DPjaOeW20vMqI4Yw==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.34.tgz", + "integrity": "sha512-T02+NXTmSRL1Mc6puz+R9CB54rSPICkXKq6+tw8B6vxZFnCPzbJxgwIX4kcluz9p8nYBjF3+lSilTGWb7+Xgew==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.34.tgz", + "integrity": "sha512-pLRip2Bh4Ng7Bf6AMgCrSp3pPe/qZyf11h5Qo2mOfJqLWzSVjxrXW+CFRJfrOVP7TCnh/gmZSM2AFdCPB72vtw==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.34.tgz", + "integrity": "sha512-vpidSJEBxx6lf1NWgXC+DCmGqesJuZ5Y8aQVVsaoO4i8tRXbXb0whChRvop/zd3nfNM4dIl5EXAky0knRX5I6w==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.34.tgz", + "integrity": "sha512-m0HBjePhe0hAQJgtMRMNV9kMgIyV4/qSnzPx42kRMQBcPhgjAq1JRu4Il26czC+9FgpMbFkUktb07f/Lwnc6CA==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.34.tgz", + "integrity": "sha512-cpRc2B94L1KvMPPYB4D6G39jLqpKlD3noAMY4/e86iXXXkhUYJJEtTuyNFTa9JRpWM0xCAp4mxjHjoIiLuoCLA==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.34.tgz", + "integrity": "sha512-8nQaEaoW7MH/K/RlozJa+lE1ejHIr8fuPIHhc513UebRav7HtXgQvxHQ6VZRUkWtep23M6dd7UqhwO1tMOfzQQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.34.tgz", + "integrity": "sha512-Y3of4qQoLLlAgf042MlrY1P+7PnN9zWj8nVtw9XQG5hcLOZLz7IKpU35oeu7n4wvyaZHwvQqDJ93gRLqdJekcQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.34.tgz", + "integrity": "sha512-9lpq1NcJqssAF7alCO6zL3gvBVVt/lKw4oetUM7OgNnRX0OWpB+ZIO9FwCrSj/dMdmgDhPLf+119zB8QxSMmAg==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.34.tgz", + "integrity": "sha512-IlWaGtj9ir7+Nrume1DGcyzBDlK8GcnJq0ANKwcI9pVw8tqr+6GD0eqyF9SF1mR8UmAp+odrx1H5NdR2cHdFHA==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.34.tgz", + "integrity": "sha512-k3or+01Rska1AjUyNjA4buEwB51eyN/xPQAoOx1CjzAQC3l8rpjUDw55kXyL63O/1MUi4ISvtNtl8gLwdyEcxw==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.34.tgz", + "integrity": "sha512-+qxb8M9FfM2CJaVU7GgYpJOHM1ngQOx+/VrtBjb4C8oVqaPcESCeg2anjl+HRZy8VpYc71q/iBYausPPbJ+Keg==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.34.tgz", + "integrity": "sha512-Y717ltBdQ5j5sZIHdy1DV9kieo0wMip0dCmVSTceowCPYSn1Cg33Kd6981+F/3b9FDMzNWldZFOBRILViENZSA==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.34.tgz", + "integrity": "sha512-bDDgYO4LhL4+zPs+WcBkXph+AQoPcQRTv18FzZS0WhjfH8TZx2QqlVPGhmhZ6WidrY+jKthUqO6UhGyIb4MpmA==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.34.tgz", + "integrity": "sha512-cfaFGXdRt0+vHsjNPyF0POM4BVSHPSbhLPe8mppDc7GDDxjIl08mV1Zou14oDWMp/XZMjYN1kWYRSfftiD0vvQ==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.34.tgz", + "integrity": "sha512-vmy9DxXVnRiI14s8GKuYBtess+EVcDALkbpTqd5jw4XITutIzyB7n4x0Tj5utAkKsgZJB22lLWGekr0ABnSLow==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.34.tgz", + "integrity": "sha512-eNPVatNET1F7tRMhii7goL/eptfxc0ALRjrj9SPFNqp0zmxrehBFD6BaP3R4LjMn6DbMO0jOAnTLFKr8NqcJAA==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.34.tgz", + "integrity": "sha512-EFhpXyHEcnqWYe2rAHFd8dRw8wkrd9U+9oqcyoEL84GbanAYjiiIjBZsnR8kl0sCQ5w6bLpk7vCEIA2VS32Vcg==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.34.tgz", + "integrity": "sha512-a8fbl8Ky7PxNEjf1aJmtxdDZj32/hC7S1OcA2ckEpCJRTjiKslI9vAdPpSjrKIWhws4Galpaawy0nB7fjHYf5Q==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.34.tgz", + "integrity": "sha512-EYvmKbSa2B3sPnpC28UEu9jBK5atGV4BaVRE7CYGUci2Hlz4AvtV/LML+TcDMT6gBgibnN2gcltWclab3UutMg==", + "dev": true, + "optional": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=", + "dev": true + }, + "jsonc-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", + "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", + "dev": true + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "dev": true, + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "lodash-unified": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.2.tgz", + "integrity": "sha512-OGbEy+1P+UT26CYi4opY4gebD8cWRDxAT6MAObIVQMiqYdxZr1g3QHWCToVsm31x2NkLS4K3+MC2qInaRMa39g==", + "requires": {} + }, + "lru-cache": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.0.tgz", + "integrity": "sha512-AmXqneQZL3KZMIgBpaPTeI6pfwh+xQ2vutMsyqOu1TBdEXFZgpG/80wuJ531w2ZN7TI0/oc8CPxzh/DKQudZqg==", + "dev": true + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "nanoid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==" + }, + "normalize-wheel-es": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.1.2.tgz", + "integrity": "sha512-scX83plWJXYH1J4+BhAuIHadROzxX0UBF3+HuZNY2Ks8BciE7tSTQ+5JhTsvzjaO0/EJdm4JBGrfObKxFf3Png==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "postcss": { + "version": "8.4.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz", + "integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==", + "requires": { + "nanoid": "^3.3.1", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "requires": { + "asap": "~2.0.3" + } + }, + "pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "dev": true, + "requires": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dev": true, + "requires": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "dev": true, + "requires": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==", + "dev": true + }, + "pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dev": true, + "requires": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dev": true, + "requires": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dev": true, + "requires": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dev": true, + "requires": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "dev": true + }, + "pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dev": true, + "requires": { + "pug-error": "^2.0.0" + } + }, + "pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "dev": true + }, + "request-light": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.5.7.tgz", + "integrity": "sha512-i/wKzvcx7Er8tZnvqSxWuNO5ZGggu2UgZAqj/RyZ0si7lBTXL7kZiI/dWxzxnQjaY7s5HEy1qK21Do4Ncr6cVw==", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.70.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", + "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "semver": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz", + "integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==", + "dev": true, + "requires": { + "lru-cache": "^7.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=", + "dev": true + }, + "typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true + }, + "upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true + }, + "vite": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.1.tgz", + "integrity": "sha512-vSlsSdOYGcYEJfkQ/NeLXgnRv5zZfpAsdztkIrs7AZHV8RCMZQkwjo4DS5BnrYTqoWqLoUe1Cah4aVO4oNNqCQ==", + "dev": true, + "requires": { + "esbuild": "^0.14.27", + "fsevents": "~2.3.2", + "postcss": "^8.4.12", + "resolve": "^1.22.0", + "rollup": "^2.59.0" + } + }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", + "dev": true + }, + "vscode-css-languageservice": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-5.4.1.tgz", + "integrity": "sha512-W7D3GKFXf97ReAaU4EZ2nxVO1kQhztbycJgc1b/Ipr0h8zYWr88BADmrXu02z+lsCS84D7Sr4hoUzDKeaFn2Kg==", + "dev": true, + "requires": { + "vscode-languageserver-textdocument": "^1.0.4", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.3" + } + }, + "vscode-html-languageservice": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-4.2.4.tgz", + "integrity": "sha512-1HqvXKOq9WlZyW4HTD+0XzrjZoZ/YFrgQY2PZqktbRloHXVAUKm6+cAcvZi4YqKPVn05/CK7do+KBHfuSaEdbg==", + "dev": true, + "requires": { + "vscode-languageserver-textdocument": "^1.0.4", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.3" + } + }, + "vscode-json-languageservice": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz", + "integrity": "sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==", + "dev": true, + "requires": { + "jsonc-parser": "^3.0.0", + "vscode-languageserver-textdocument": "^1.0.3", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.3" + }, + "dependencies": { + "jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + } + } + }, + "vscode-jsonrpc": { + "version": "8.0.0-next.7", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.0-next.7.tgz", + "integrity": "sha512-JX/F31LEsims0dAlOTKFE4E+AJMiJvdRSRViifFJSqSN7EzeYyWlfuDchF7g91oRNPZOIWfibTkDf3/UMsQGzQ==", + "dev": true + }, + "vscode-languageserver": { + "version": "8.0.0-next.10", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.0.0-next.10.tgz", + "integrity": "sha512-sdjldl9ipuBSWVw5ENVMRcOVQwF0o+J6+lNA7FrB8MiLmzflnfjRoJMqA5tCEY8S/J/+P56ZR/dqiQnRYg5m8w==", + "dev": true, + "requires": { + "vscode-languageserver-protocol": "3.17.0-next.16" + } + }, + "vscode-languageserver-protocol": { + "version": "3.17.0-next.16", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.16.tgz", + "integrity": "sha512-tx4DnXw9u3N7vw+bx6n2NKp6FoxoNwiP/biH83AS30I2AnTGyLd7afSeH6Oewn2E8jvB7K15bs12sMppkKOVeQ==", + "dev": true, + "requires": { + "vscode-jsonrpc": "8.0.0-next.7", + "vscode-languageserver-types": "3.17.0-next.9" + }, + "dependencies": { + "vscode-languageserver-types": { + "version": "3.17.0-next.9", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.9.tgz", + "integrity": "sha512-9/PeDNPYduaoXRUzYpqmu4ZV9L01HGo0wH9FUt+sSHR7IXwA7xoXBfNUlv8gB9H0D2WwEmMomSy1NmhjKQyn3A==", + "dev": true + } + } + }, + "vscode-languageserver-textdocument": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz", + "integrity": "sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ==", + "dev": true + }, + "vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==", + "dev": true + }, + "vscode-nls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.0.0.tgz", + "integrity": "sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==", + "dev": true + }, + "vscode-pug-languageservice": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vscode-pug-languageservice/-/vscode-pug-languageservice-0.29.8.tgz", + "integrity": "sha512-QHYAzDSJLg7GOLxCZ12qsM0dAM0dPeMSS1t4kKfzLsfpErmZpFzkAIXbidVrNMdMffGZMtTuIlcpEyWHbx96Iw==", + "dev": true, + "requires": { + "@volar/code-gen": "0.29.8", + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8", + "@volar/transforms": "0.29.8", + "pug-lexer": "^5.0.1", + "pug-parser": "^6.0.0", + "vscode-languageserver": "^8.0.0-next.2" + } + }, + "vscode-typescript-languageservice": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vscode-typescript-languageservice/-/vscode-typescript-languageservice-0.29.8.tgz", + "integrity": "sha512-eecDqHk4WjEvy6VHQ6teHczppQ9yJO2wExCy7yu7WiFj35qbw0h4G6Erv46MvP3ClL8FggFzD7s1qM6vdqJUfw==", + "dev": true, + "requires": { + "@volar/shared": "0.29.8", + "semver": "^7.3.5", + "upath": "^2.0.1", + "vscode-languageserver": "^8.0.0-next.2", + "vscode-languageserver-textdocument": "^1.0.1" + } + }, + "vscode-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.3.tgz", + "integrity": "sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==", + "dev": true + }, + "vscode-vue-languageservice": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vscode-vue-languageservice/-/vscode-vue-languageservice-0.29.8.tgz", + "integrity": "sha512-qSJdvW5ttyGUB/8uWDKgo8vnIoFnXYlBP4Z/cn54btsRn6ZMw7IJGJU1381e7p/yGvMTLeGbugD53SghbnSa6g==", + "dev": true, + "requires": { + "@volar/code-gen": "0.29.8", + "@volar/html2pug": "0.29.8", + "@volar/shared": "0.29.8", + "@volar/source-map": "0.29.8", + "@volar/transforms": "0.29.8", + "@volar/vue-code-gen": "0.29.8", + "@vscode/emmet-helper": "^2.8.0", + "@vue/reactivity": "^3.2.21", + "@vue/shared": "^3.2.21", + "request-light": "^0.5.4", + "upath": "^2.0.1", + "vscode-css-languageservice": "^5.1.7", + "vscode-html-languageservice": "^4.1.0", + "vscode-json-languageservice": "^4.1.8", + "vscode-languageserver": "^8.0.0-next.2", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-pug-languageservice": "0.29.8", + "vscode-typescript-languageservice": "0.29.8" + } + }, + "vue": { + "version": "3.2.31", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.31.tgz", + "integrity": "sha512-odT3W2tcffTiQCy57nOT93INw1auq5lYLLYtWpPYQQYQOOdHiqFct9Xhna6GJ+pJQaF67yZABraH47oywkJgFw==", + "requires": { + "@vue/compiler-dom": "3.2.31", + "@vue/compiler-sfc": "3.2.31", + "@vue/runtime-dom": "3.2.31", + "@vue/server-renderer": "3.2.31", + "@vue/shared": "3.2.31" + } + }, + "vue-loading-overlay": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-5.0.3.tgz", + "integrity": "sha512-6JWZalwlHF4do3HXsFZGt6PcWYseAI5FuNKpveEkljkzqskDWRr7rYmYHVx2kKu4qIvK0vLpL25T/hpFMNoevQ==", + "requires": {} + }, + "vue-tsc": { + "version": "0.29.8", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.29.8.tgz", + "integrity": "sha512-pT0wLRjvRuSmB+J4WJT6uuV9mO0KtSSXEAtaVXZQzyk5+DJdbLIQTbRce/TXSkfqt1l1WogO78RjtOJFiMCgfQ==", + "dev": true, + "requires": { + "@volar/shared": "0.29.8", + "vscode-vue-languageservice": "0.29.8" + } + }, + "with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dev": true, + "requires": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2d04609 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "bj-casino-rank", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@ant-design/icons-vue": "^6.1.0", + "@popperjs/core": "^2.11.5", + "axios": "^0.26.1", + "bootstrap": "^5.1.3", + "dayjs": "^1.11.2", + "element-plus": "^2.1.9", + "vue": "^3.2.25", + "vue-loading-overlay": "^5.0.3" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^2.3.0", + "typescript": "^4.5.4", + "vite": "^2.9.0", + "vue-tsc": "^0.29.8" + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..478569c Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..eca6ef9 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/src/assets/fonts.css b/src/assets/fonts.css new file mode 100644 index 0000000..679ef69 --- /dev/null +++ b/src/assets/fonts.css @@ -0,0 +1,7 @@ +@font-face { + /* 重命名字体名 */ + font-family: 'Zen Maru Gothic'; + src: url('./fonts/ZenMaruGothic-Regular.ttf'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/src/assets/fonts/ZenMaruGothic-Regular.ttf b/src/assets/fonts/ZenMaruGothic-Regular.ttf new file mode 100644 index 0000000..b491f5b Binary files /dev/null and b/src/assets/fonts/ZenMaruGothic-Regular.ttf differ diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000..f3d2503 Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/assets/style.css b/src/assets/style.css new file mode 100644 index 0000000..bd090f4 --- /dev/null +++ b/src/assets/style.css @@ -0,0 +1,16 @@ +.BJ_Casino_Bot { + /* float: left; */ + border-width: 3px; + border-style: double; + border-color: #000000; + padding: 5px; + height: 130px; +} + +.BJ_Casino_BotController { + /* float: left; */ + border-width: 1px; + border-style: dashed; + border-color: #000000; + padding: 5px; +} \ No newline at end of file diff --git a/src/components/BJ_Casino_Bot.vue b/src/components/BJ_Casino_Bot.vue new file mode 100644 index 0000000..aa69ba3 --- /dev/null +++ b/src/components/BJ_Casino_Bot.vue @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/src/components/BJ_Casino_BotController.vue b/src/components/BJ_Casino_BotController.vue new file mode 100644 index 0000000..9f6e723 --- /dev/null +++ b/src/components/BJ_Casino_BotController.vue @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/src/components/BJ_Casino_Bot_Info.vue b/src/components/BJ_Casino_Bot_Info.vue new file mode 100644 index 0000000..212c8f5 --- /dev/null +++ b/src/components/BJ_Casino_Bot_Info.vue @@ -0,0 +1,13 @@ + + + \ No newline at end of file diff --git a/src/components/BJ_Casino_Bot_Lobby.vue b/src/components/BJ_Casino_Bot_Lobby.vue new file mode 100644 index 0000000..e0810a9 --- /dev/null +++ b/src/components/BJ_Casino_Bot_Lobby.vue @@ -0,0 +1,30 @@ + + + \ No newline at end of file diff --git a/src/components/BJ_Casino_Bot_Slot.vue b/src/components/BJ_Casino_Bot_Slot.vue new file mode 100644 index 0000000..b5ce7e9 --- /dev/null +++ b/src/components/BJ_Casino_Bot_Slot.vue @@ -0,0 +1,28 @@ + + + \ No newline at end of file diff --git a/src/components/BJ_Casino_Magnification.vue b/src/components/BJ_Casino_Magnification.vue new file mode 100644 index 0000000..76073d7 --- /dev/null +++ b/src/components/BJ_Casino_Magnification.vue @@ -0,0 +1,67 @@ + + + \ No newline at end of file diff --git a/src/components/BJ_Casino_WinMoney.vue b/src/components/BJ_Casino_WinMoney.vue new file mode 100644 index 0000000..c1e28ac --- /dev/null +++ b/src/components/BJ_Casino_WinMoney.vue @@ -0,0 +1,67 @@ + + + \ No newline at end of file diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..aafef95 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,8 @@ +/// + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..74322b8 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,12 @@ +import "@popperjs/core"; +import "bootstrap"; +import "bootstrap/dist/css/bootstrap.min.css"; +import ElementPlus from "element-plus"; +import "element-plus/dist/index.css"; +import locale from "element-plus/lib/locale/lang/zh-tw"; +import { createApp } from "vue"; +import App from "./App.vue"; +import "./script/Engine/CatanEngine/CSharp/String"; + + +createApp(App).use(ElementPlus, { locale }).mount("#app"); diff --git a/src/script/BJ_Casino_Bot.ts b/src/script/BJ_Casino_Bot.ts new file mode 100644 index 0000000..2c333b9 --- /dev/null +++ b/src/script/BJ_Casino_Bot.ts @@ -0,0 +1,166 @@ +import { Ref, ref } from "vue"; +import CSMessage from "./Base/CSMessage"; +import { AccountLoginRequest, CustomLoginRequest } from "./Base/Request/AccountRequest"; +import { BJ_Casino_Bot_Lobby } from "./BJ_Casino_Bot_Lobby"; +import { BJ_Casino_Bot_Slot } from "./BJ_Casino_Bot_Slot"; +import { BJ_Casino_UserData } from "./BJ_Casino_Userdata"; +import { INetResponse } from "./Engine/CatanEngine/NetManagerV2/Core/INetResponse"; +import { NetConnector } from "./Engine/CatanEngine/NetManagerV2/NetConnector"; +import { NetManager } from "./Engine/CatanEngine/NetManagerV2/NetManager"; +import { Tools } from "./Tools"; + +export class BJ_Casino_Bot { + //#region public + + public UserData: BJ_Casino_UserData = null!; + + public LobbyScript: BJ_Casino_Bot_Lobby = null!; + + public SlotScript: BJ_Casino_Bot_Slot = null!; + + // Main + public Log: Ref = ref(""); + + // Info + public AID: Ref = ref(""); + public NickName: Ref = ref(""); + public Money: Ref = ref(0); + public Level: Ref = ref(0); + public Exp: Ref = ref(0); + + // Lobby + public LobbyShow: Ref = ref(false); + + // Slot + public SlotShow: Ref = ref(false); + + //#endregion + + //#region private + + private _client: any; + + private _conn: NetConnector = null!; + + //#endregion + + //#region Lifecycle + + /** + * + */ + constructor(client: any) { + this._client = client; + this.onLoad(); + } + + public async onLoad(): Promise { + await this._login(); + } + + //#endregion + + //#region Custom + + private async _login(): Promise { + let self: this = this; + // const URL: string = "https://game.online-bj.com"; + // const Port: string = "9005"; + const URL: string = "http://220.134.195.1"; + const Port: string = "19005"; + await this.ConnectAsync(URL, +Port); + let a: string = "TS000001"; + let p: string = "a123456"; + // 取得帳號資料 + let resp: any = await this._accountLogin(a, p); + await this._getAccountInfo(resp.a, resp.pw); + this.LobbyShow.value = true; + this._setUI(); + } + private async _accountLogin(account: string, password: string): Promise { + let req: CustomLoginRequest = new CustomLoginRequest(account, password); + await req.SendAsync(true); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + CSMessage.NetError(resp.Method, resp.Status, "Registe Account Error!"); + return; + } + return resp.Data; + } + + private async _getAccountInfo(a: string, pw: string): Promise { + // 取得帳號資料 + let req: AccountLoginRequest = new AccountLoginRequest(a, pw); + await req.SendAsync(true); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + CSMessage.NetError(resp.Method, resp.Status, "Login Account Error!"); + return; + } + this.UserData = new BJ_Casino_UserData(resp.Data["id"].toString(), resp.Data["name"].toString(), +resp.Data["m"], +resp.Data["lv"], +resp.Data["exp"]); + } + + private _setUI(): void { + this.AID.value = this.UserData.AID; + this.NickName.value = this.UserData.NickName; + this.Money.value = this.UserData.Money; + this.Level.value = this.UserData.Level; + this.Exp.value = this.UserData.Exp; + } + + public AddLog(log: string): void { + console.log(log); + this.Log.value += log + "\n"; + const textarea: HTMLElement | null = document.getElementById("DIV_LOG")!; + if (textarea) { + textarea.scrollTop = textarea.scrollHeight; + } + } + + //#endregion + + //#region Onclick + + //#endregion + + //#region 網路相關 + + /** 連線(目前沒有重連機制) */ + public async ConnectAsync(host: string, port: number): Promise { + var url: string = "https://api.ipify.org/?format=json"; + var xhr: XMLHttpRequest = new XMLHttpRequest(); + let ip: string = ""; + xhr.onreadystatechange = function (): void { + if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 400)) { + ip = JSON.parse(xhr.responseText)["ip"]; + } + }; + xhr.open("GET", url, true); + xhr.send(); + this.AddLog("[事件]準備連線..."); + while (ip === "") { + await Tools.Sleep(1); + } + this._conn = new NetConnector(host, port, ip); + this._conn.OnDataReceived.AddCallback(this._onNetDataReceived, this); + this._conn.OnDisconnected.AddCallback(this._onNetDisconnected, this); + NetManager.Initialize(this._conn); + this.AddLog("[事件]連線中..."); + // 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect() + await NetManager.ConnectAsync(); + this.AddLog(String.Format("[事件]連線狀態: {0}", NetManager.IsConnected)); + } + + private _onNetDisconnected(): void { + this.AddLog("[事件] 收到連線中斷事件"); + this._conn.OnDataReceived.RemoveAllCallbacks(); + // MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.NetDisconnected]); + } + + private _onNetDataReceived(resp: INetResponse): void { + this.AddLog(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); + // MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.ServerData, resp]); + } + + //#endregion +} diff --git a/src/script/BJ_Casino_BotController.ts b/src/script/BJ_Casino_BotController.ts new file mode 100644 index 0000000..b2dd53a --- /dev/null +++ b/src/script/BJ_Casino_BotController.ts @@ -0,0 +1,48 @@ +// import { BJ_Casino_Data } from "./BJ_Casino_Data"; + +export class BJ_Casino_BotController { + //#region Lifecycle + + // public BJ_Casino: BJ_Casino_Data | undefined; + + //#endregion + + //#region private + + private _client: any; + + //#endregion + + //#region Lifecycle + + /** + * + */ + constructor(client: any) { + this._client = client; + // this.BJ_Casino = client.BJ_Casino; + // this.onLoad(); + } + + // public async onLoad() { + // await this.SetInit(); + // }; + + // public async SetInit() { + // while (this.BJ_Casino?.Client.isLoading.value) { + // await Tools.Sleep(50); + // } + // this._client.Title.value = this.BJ_Casino?.Title; + // this.SendData(); + // }; + + //#endregion + + //#region Custom + + // public SendData() { + // this._client.RankData.value = this.BJ_Casino?.RankWinMoneyData; + // } + + //#endregion +} diff --git a/src/script/BJ_Casino_Bot_Lobby.ts b/src/script/BJ_Casino_Bot_Lobby.ts new file mode 100644 index 0000000..767e77e --- /dev/null +++ b/src/script/BJ_Casino_Bot_Lobby.ts @@ -0,0 +1,133 @@ +import { Ref, ref } from "vue"; +import CSMessage from "./Base/CSMessage"; +import { BJ_Casino_Bot } from "./BJ_Casino_Bot"; +import { SeatListRequest } from "./Common/ChooseSeat/ChooseSeatRequest"; +import { SlotInRequest } from "./Common/Subgame/GameRequest"; +import { INetResponse } from "./Engine/CatanEngine/NetManagerV2/Core/INetResponse"; + +export class BJ_Casino_Bot_Lobby { + //#region public + + public LobbyCongig: any[] = [2, [ + "不選擇資源路徑", + "體驗聽", + "一般聽", + "高手聽", + "至尊聽", + ]]; + + public LobbyShow: Ref = ref(false); + public Lobby: Ref = ref(0); + public Slot: Ref = ref(""); + public Table: Ref = ref(0); + public LobbyDefault: Ref = ref(""); + + //#endregion + + //#region private + + private _bj_Casino_Bot: BJ_Casino_Bot; + + //#endregion + + //#region Lifecycle + + /** + * + */ + constructor(bj_Casino_Bot: BJ_Casino_Bot) { + this._bj_Casino_Bot = bj_Casino_Bot; + this.onLoad(); + } + + public async onLoad(): Promise { + this.Lobby.value = this.LobbyCongig[0]; + this.LobbyDefault.value = this.LobbyCongig[1][this.Lobby.value]; + } + + //#endregion + + //#region Custom + + public GetLobby(): { key: string; value: string; label: string; }[] { + const patchs: any[] = this.LobbyCongig[1]; + let options: any[] = []; + for (let i: number = 0; i < patchs.length; i++) { + const patch: any = patchs[i]; + options.push({ + value: i, + label: patch, + }); + } + return options; + } + + public SelectLobby(data: any): void { + // data为el-option上:value绑定的对象 + this.Lobby.value = data; + } + + //#endregion + + //#region Onclick + + public async OnclickSlotIn(hall: number, slot: number): Promise { + let table: number = 1; + let req: SeatListRequest = new SeatListRequest(hall, slot); + await req.SendAsync(true); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + CSMessage.NetError(resp.Method, resp.Status, "機台列表獲取失敗"); + return; + } + let data: any = resp.Data; + for (let i: number = 0; i < data.length; i++) { + const element: any = data[i]; + if (element[0].length > 0) { + let aid: string = element[0][0]; + if (aid === this._bj_Casino_Bot.UserData.AID) { + table = i + 1; + break; + } else { + table = i + 1; + break; + } + } + } + let resp_slotIn: any = await this._slotIn(hall, slot, table); + this.Table.value = table; + this._bj_Casino_Bot.SlotScript.GameIn(resp_slotIn); + this._bj_Casino_Bot.SlotShow.value = true; + return; + } + + private async _slotIn(hall: number, slot: number, uid: number): Promise { + let req: SlotInRequest = new SlotInRequest(slot, hall, uid); + await req.SendAsync(true); + let resp: INetResponse = req.Result; + if (resp.IsValid) { + this._bj_Casino_Bot.AddLog(`進機台成功 slot: ${slot}, hall: ${hall}, table: ${uid}`); + return resp; + } else { + switch (resp.Status) { + case 11: + // this._messageInfo(1003); + break; + case 101: + // CSMessage.CreateYesMsg(CSSettingsV3.prototype.CommonString(16)); + break; + default: + break; + } + CSMessage.NetError(resp.Method, resp.Status, "進遊戲失敗"); + } + } + + public OnclickChangeSlot(): void { + // await this._login(); + } + + //#endregion + + //#endregion +} diff --git a/src/script/BJ_Casino_Bot_Slot.ts b/src/script/BJ_Casino_Bot_Slot.ts new file mode 100644 index 0000000..be291da --- /dev/null +++ b/src/script/BJ_Casino_Bot_Slot.ts @@ -0,0 +1,95 @@ +import { Ref, ref } from "vue"; +import { BJ_Casino_Bot } from "./BJ_Casino_Bot"; +import { Tools } from "./Tools"; + +export class BJ_Casino_Bot_Slot { + //#region public + + public BetDefault: Ref = ref(""); + + public SpinDelay: Ref = ref(1); + + public GameInData: any = null!; + + public BetGroup: number[] = []; + + public NowBetIndex: number = null!; + + //#endregion + + //#region private + + private _bj_Casino_Bot: BJ_Casino_Bot; + + private _isSpin: boolean = false; + + private _isRun: boolean = false; + + //#endregion + + //#region get set + + public get NowBet(): number { return this.BetGroup[this.NowBetIndex]; } + + //#endregion + + //#region Lifecycle + + /** + * + */ + constructor(bj_Casino_Bot: BJ_Casino_Bot) { + this._bj_Casino_Bot = bj_Casino_Bot; + this.onLoad(); + } + + public async onLoad(): Promise { + // + } + + public async GameIn(gameInData: any): Promise { + this.GameInData = gameInData; + let Data: any = gameInData.Data; + this.BetGroup = Data.br; + this.NowBetIndex = Data.db; + this.BetDefault.value = this.BetGroup[Data.db].toString(); + } + + //#endregion + + //#region Custom + + public async Spin(): Promise { + this._isRun = true; + this._bj_Casino_Bot.AddLog(`Spin Bet: ${this.NowBet}`); + await Tools.Sleep(this.SpinDelay.value * 1000); + if (this._isSpin) { + this.Spin(); + } else { + this._isRun = false; + } + } + + public SelectBet(data: any): void { + this.NowBetIndex = data; + this._bj_Casino_Bot.AddLog(`改變Bet: ${this.NowBet}`); + } + + //#endregion + + //#region Onclick + + public async OnclickSpin(): Promise { + if (this._isRun) { + return; + } + this._isSpin = true; + this.Spin(); + } + + public async OnclickStop(): Promise { + this._isSpin = false; + } + + //#endregion +} diff --git a/src/script/BJ_Casino_Data.ts b/src/script/BJ_Casino_Data.ts new file mode 100644 index 0000000..1e4a4ad --- /dev/null +++ b/src/script/BJ_Casino_Data.ts @@ -0,0 +1,561 @@ +import moment from "moment"; +import CSMessage from "./Base/CSMessage"; +import { AccountLoginRequest } from "./Base/Request/AccountRequest"; +import { AppRankHistory, AppRankInfo } from "./Base/Request/RankRequest"; +import "./Engine/CatanEngine/CSharp/String"; +import { INetResponse } from "./Engine/CatanEngine/NetManagerV2/Core/INetResponse"; +import { NetConnector } from "./Engine/CatanEngine/NetManagerV2/NetConnector"; +import { NetManager } from "./Engine/CatanEngine/NetManagerV2/NetManager"; +import { Tools } from "./Tools"; + +export class BJ_Casino_Data { + + //#region public + + public ContestData: string[] = ["5/9~5/15", "5/16~5/22"]; + + public Title: string = ""; + + public Client: any; + + public Current: any[] = []; + + //#endregion + + //#region private + + private _conn: NetConnector = null!; + private _ws: any; + + private _rankMagnificationData: any[] = []; + private _rankWinMoneyData: any[] = []; + + private _nowSearchMagnificationID: number = 0; + + private _nowSearchWinMoneyID: number = 0; + + private _nowContestIndex: number = 0; + + private _nowContestStartIndex: number = 0; + + private _nowContestEndIndex: number = 0; + + private _nowContestID: number = 0; + + private _nowContestDate: string = ""; + + private _nowContestStart: string = ""; + + private _nowContestEnd: string = ""; + + private _isIDupup: boolean = false; + + /** + * 0 _rankMagnificationData + * 1 _rankWinMoneyData + */ + private _isOK: any[] = [false, false]; + + //#endregion + + //#region get set + + public get RankMagnificationData(): any[] { return this._rankMagnificationData; } + + public get RankWinMoneyData(): any[] { return this._rankWinMoneyData; } + + //#endregion + + //#region Lifecycle + + /** + * + */ + constructor(client: any) { + this.Client = client; + this.onLoad(); + } + + public async onLoad(): Promise { + await this.ConnectServer(); + await this.SendRankData(); + } + + public SetCurrent(current: any): void { + this.Current.push(current); + } + + //#endregion + + //#region 網路相關 + + /** 連線 */ + public async ConnectServer(): Promise { + const URL: string = "https://game.online-bj.com"; + const Port: string = "9005"; + await this.ConnectAsync(URL, +Port); + // 取得帳號資料 + let req: AccountLoginRequest = new AccountLoginRequest("ct00000691", "4lsAyoalajm7"); + await req.SendAsync(true); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + CSMessage.NetError(resp.Method, resp.Status, "Login Account Error!"); + return; + } + } + + /** 連線(目前沒有重連機制) */ + public async ConnectAsync(host: string, port: number): Promise { + var url: string = "https://api.ipify.org/?format=json"; + var xhr: XMLHttpRequest = new XMLHttpRequest(); + let ip: string = ""; + xhr.onreadystatechange = function (): void { + if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 400)) { + ip = JSON.parse(xhr.responseText)["ip"]; + } + }; + xhr.open("GET", url, true); + xhr.send(); + console.log("[事件]準備連線..."); + while (ip === "") { + await Tools.Sleep(1); + } + this._conn = new NetConnector(host, port, ip); + this._conn.OnDataReceived.AddCallback(this._onNetDataReceived, this); + this._conn.OnDisconnected.AddCallback(this._onNetDisconnected, this); + NetManager.Initialize(this._conn); + console.log("[事件]連線中..."); + // 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect() + await NetManager.ConnectAsync(); + console.log(String.Format("[事件]連線狀態: {0}", NetManager.IsConnected)); + } + + private _onNetDisconnected(): void { + console.log("[事件] 收到連線中斷事件"); + this._conn.OnDataReceived.RemoveAllCallbacks(); + // MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.NetDisconnected]); + } + + private _onNetDataReceived(resp: INetResponse): void { + console.log(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); + // MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.ServerData, resp]); + } + + //#endregion + + //#region Custom + + public async SendRankData(): Promise { + this.SendRankMagnificationData(); + this.SendRankWinMoneyData(); + } + + public async SendRankMagnificationData(): Promise { + let req: any = null; + req = new AppRankInfo(12, 2); + await req.SendAsync(true); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + if (resp.Status === 11) { + CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); + this.OrganizeRankMagnificationData(this._rankMagnificationData); + this.SetRankMagnificationDataOK(); + } else { + CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); + } + return; + } + this.SetRankMagnificationSearchData(resp.Data); + this.ParseRankMagnificationData(resp.Data); + } + + public async SendRankWinMoneyData(): Promise { + let req: any = null; + req = new AppRankInfo(11, 2); + await req.SendAsync(true); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + if (resp.Status === 11) { + CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); + this.OrganizeRankMagnificationData(this._rankMagnificationData); + this.SetRankMagnificationDataOK(); + } else { + CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); + } + return; + } + this.SetRankWinMoneySearchData(resp.Data); + this.ParseRankWinMoneyData(resp.Data); + } + + public SetRankMagnificationSearchData(data: any): void { + let id: number = +data["id"]; + this._nowSearchMagnificationID = id; + this._nowContestID = id; + this._nowContestDate = moment().format("MM/DD"); + for (let i: number = 0; i < this.ContestData.length; i++) { + const contest: string = this.ContestData[i]; + let str: string[] = contest.split("~"); + let my: moment.Moment = this._getMomentFormString(this._nowContestDate); + let start: moment.Moment = this._getMomentFormString(str[0]); + let end: moment.Moment = this._getMomentFormString(str[1]); + let diff: number = my.diff(end, "day"); + if (diff <= 0) { + this._nowContestIndex = i; + this._nowContestStart = moment(start).format("MM/DD"); + this._nowContestEnd = moment(end).format("MM/DD"); + this._nowContestStartIndex = this._contestIDFormDate(this._nowContestStart); + this._nowContestEndIndex = this._contestIDFormDate(this._nowContestEnd); + break; + } + } + this.Title = `${this._nowContestStart}~${this._nowContestEnd}`; + } + + public async ParseRankMagnificationData(data: any = null): Promise { + let id: number = this._nowSearchMagnificationID; + if (data) { + this.RankDataAddDate(id, data["rank"]); + this._rankMagnificationData = this._rankMagnificationData.concat(data["rank"]); + } + let targetIndex: number = this._nowContestStartIndex; + if (this._isIDupup) { + targetIndex = this._nowContestEndIndex; + } + if (id !== targetIndex) { + if (this._isIDupup) { + this._nowSearchMagnificationID = id + 1; + } else { + this._nowSearchMagnificationID = id - 1; + } + let req: any = await this.GetRankData(12, this._nowSearchMagnificationID); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + if (resp.Status === 11) { + CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); + this.ParseRankMagnificationData(resp.Data); + } else { + CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); + } + return; + } + this.ParseRankMagnificationData(resp.Data); + return; + } else { + this.OrganizeRankMagnificationData(this._rankMagnificationData); + this.SetRankMagnificationDataOK(); + } + } + + public async GetRankData(type: number, dayIdid: number): Promise { + let req: any = null; + req = new AppRankHistory(type, 2, dayIdid); + if (dayIdid === this._nowContestID) { + req = new AppRankInfo(type, 2); + } + await req.SendAsync(true); + return req; + } + + public OrganizeRankMagnificationData(rankdata: any): void { + rankdata.sort((a: any, b: any) => { + return b[1] - a[1]; + }); + rankdata = rankdata.filter((rankdata: any, index: any, arr: any) => { + return arr.findIndex((s: any) => rankdata[2][1] === s[2][1]) === index; + }); + for (let i: number = 0; i < rankdata.length; i++) { + rankdata[i][0] = i + 1; + } + this._rankMagnificationData = rankdata; + } + + public SetRankMagnificationDataOK(): void { + this._isOK[0] = true; + this._checkOK(); + } + + public SetRankWinMoneySearchData(data: any): void { + let id: number = +data["id"]; + this._nowSearchWinMoneyID = id; + } + + public async ParseRankWinMoneyData(data: any = null): Promise { + let id: number = this._nowSearchWinMoneyID; + if (data) { + this.RankDataAddDate(id, data["rank"]); + this._rankWinMoneyData = this._rankWinMoneyData.concat(data["rank"]); + } + let targetIndex: number = this._nowContestStartIndex; + if (this._isIDupup) { + targetIndex = this._nowContestEndIndex; + } + if (id !== targetIndex) { + if (this._isIDupup) { + this._nowSearchWinMoneyID = id + 1; + } else { + this._nowSearchWinMoneyID = id - 1; + } + let req: any = await this.GetRankData(11, this._nowSearchWinMoneyID); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + if (resp.Status === 11) { + CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); + this.ParseRankWinMoneyData(); + } else { + CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); + } + return; + } + this.ParseRankWinMoneyData(resp.Data); + return; + } else { + this.OrganizeRankWinMoneyData(this._rankWinMoneyData); + this.SetRankWinMoneyDataOK(); + } + } + + public OrganizeRankWinMoneyData(rankdata: any): void { + rankdata.sort((a: any, b: any) => { + return b[1] - a[1]; + }); + rankdata = rankdata.filter((rankdata: any, index: any, arr: any) => { + return arr.findIndex((s: any) => rankdata[2][1] === s[2][1]) === index; + }); + for (let i: number = 0; i < rankdata.length; i++) { + rankdata[i][0] = i + 1; + } + this._rankWinMoneyData = rankdata; + } + + public SetRankWinMoneyDataOK(): void { + this._isOK[1] = true; + this._checkOK(); + } + + public RankDataAddDate(id: number, rankdata: any): any { + let date: string = this._contestDateFormID(id); + for (let i: number = 0; i < rankdata.length; i++) { + rankdata[i].push(date); + } + return rankdata; + } + + private _checkOK(): void { + if (this._isOK.includes(false)) { + return; + } + NetManager.Disconnect(); + for (let i: number = 0; i < this.Current.length; i++) { + const current: any = this.Current[i]; + current.SetInit(); + } + this.Client.isLoading.value = false; + } + + public async PrevWeek(): Promise { + let nowContestIndex: number = this._nowContestIndex; + if (nowContestIndex - 1 >= 0) { + nowContestIndex--; + } else { + alert(`到底了`); + return; + } + this._isIDupup = false; + await this.RunSetWeek(nowContestIndex); + // const contest: string = this.ContestData[nowContestIndex]; + // let str: string[] = contest.split("~"); + // let my: moment.Moment = this._getMomentFormString(this._nowContestDate); + // let start: moment.Moment = this._getMomentFormString(str[0]); + // let end: moment.Moment = this._getMomentFormString(str[1]); + // let diff: number = my.diff(start, "day"); + // if (diff < 0) { + // alert(`還沒開放`); + // return; + // } + // this.Client.isLoading.value = true; + // this._isOK[0] = false; + // this._isOK[1] = false; + + // this._nowContestStart = moment(start).format("MM/DD"); + // this._nowContestEnd = moment(end).format("MM/DD"); + // this._nowContestStartIndex = this._contestIDFormDate(this._nowContestStart); + // this._nowContestEndIndex = this._nowSearchMagnificationID = this._contestIDFormDate(this._nowContestEnd); + // this.Title = `${this._nowContestStart}~${this._nowContestEnd}`; + + // await this.ConnectServer(); + // this.RunRankMagnificationWeek(); + // this.RunRankWinMoneyWeek(); + } + + public async NextWeek(): Promise { + let nowContestIndex: number = this._nowContestIndex; + if (nowContestIndex + 1 < this.ContestData.length) { + nowContestIndex++; + } else { + alert(`到底了`); + return; + } + + this._isIDupup = true; + await this.RunSetWeek(nowContestIndex); + } + + public async RunSetWeek(nowContestIndex: number): Promise { + const contest: string = this.ContestData[nowContestIndex]; + let str: string[] = contest.split("~"); + let my: moment.Moment = this._getMomentFormString(this._nowContestDate); + let start: moment.Moment = this._getMomentFormString(str[0]); + let end: moment.Moment = this._getMomentFormString(str[1]); + let diff: number = my.diff(start, "day"); + if (diff < 0) { + alert(`還沒開放`); + return; + } + this._nowContestIndex = nowContestIndex; + this.Client.isLoading.value = true; + this._isOK[0] = false; + this._isOK[1] = false; + + this._nowContestStart = moment(start).format("MM/DD"); + this._nowContestEnd = moment(end).format("MM/DD"); + this._nowContestStartIndex = this._contestIDFormDate(this._nowContestStart); + this._nowContestEndIndex = this._contestIDFormDate(this._nowContestEnd); + if (this._isIDupup) { + this._nowSearchMagnificationID = this._nowSearchWinMoneyID = this._contestIDFormDate(this._nowContestStart); + } else { + this._nowSearchMagnificationID = this._nowSearchWinMoneyID = this._contestIDFormDate(this._nowContestEnd); + } + this.Title = `${this._nowContestStart}~${this._nowContestEnd}`; + + await this.ConnectServer(); + this.RunRankMagnificationWeek(); + this.RunRankWinMoneyWeek(); + } + + public async RunRankMagnificationWeek(): Promise { + this._rankMagnificationData = []; + let req: any = await this.GetRankData(12, this._nowSearchMagnificationID); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + if (resp.Status === 11) { + CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); + this.OrganizeRankMagnificationData(this._rankMagnificationData); + this.SetRankMagnificationDataOK(); + } else { + CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); + } + return; + } + this.ParseRankMagnificationData(resp.Data); + } + + public async RunRankWinMoneyWeek(): Promise { + this._rankWinMoneyData = []; + let req: any = await this.GetRankData(11, this._nowSearchWinMoneyID); + let resp: INetResponse = req.Result; + if (!resp.IsValid) { + if (resp.Status === 11) { + CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); + this.OrganizeRankWinMoneyData(this._rankWinMoneyData); + this.SetRankWinMoneyDataOK(); + } else { + CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); + } + return; + } + this.ParseRankWinMoneyData(resp.Data); + } + + //#endregion + + //#region Get + + private _contestIDFormDate(date: string): number { + let my: moment.Moment = this._getMomentFormString(this._nowContestDate); + let target: moment.Moment = this._getMomentFormString(date); + let diffday: number = my.diff(target, "day"); + let id: number = this._nowContestID - diffday; + if (id < 0) { + return 0; + } else { + return id; + } + } + + private _contestDateFormID(id: number): string { + let my: number = this._nowContestID; + let target: number = id; + let diffid: number = my - target; + if (diffid < 0) { + diffid = 0; + } + let date: string = moment().subtract(diffid, "day").format("MM/DD"); + return date; + } + + private _getMomentFormString(str: string): moment.Moment { + let data: string[] = str.split("/"); + let m: number = +data[0] - 1; + let d: number = +data[1]; + let date: Date = new Date(); + date.setMonth(m); + date.setDate(d); + let mymoment: moment.Moment = moment(date); + return mymoment; + } + + //#endregion + + //#region Tools Function + + /** + * 陣列排序,asc&key陣列長度請一樣 + * PS. boolean 帶false是先true在false + * @link JavaScript Object 排序 http://www.eion.com.tw/Blogger/?Pid=1170#:~:text=JavaScript%20Object%20排序 + * @param Arr 需排序陣列 + * @param asc 是否升序排列(小到大) + * @param key 需排序的key(優先順序左到右)(沒有就放空) + */ + public ObjectSort(Arr: any[], asc: boolean[] = [true], key?: string[]): any[] { + if (!key || key.length === 0 || Arr.length === 0 || Arr[0][key[0]] === undefined) { + console.error(`ObjectSort key error`); + return Arr; + } else if (asc.length !== key.length) { + console.error(`ObjectSort key asc error asc.length: ${asc.length}, key.length: ${key.length}`); + return Arr; + } + let count: number = key ? key.length : 1; + for (let i: number = count - 1; i >= 0; i--) { + Arr = Arr.sort(function (a: any, b: any): 1 | -1 { + let mya: any = a; + let myb: any = b; + if (key) { + mya = a[key[i]]; + myb = b[key[i]]; + } + + // 加個等於數字相同不要再去排序到 + if (asc[i]) { + return mya >= myb ? 1 : -1; + } else { + return mya <= myb ? 1 : -1; + } + }); + } + return Arr; + } + + public Sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + public AddLog(log: any): void { + console.log(log); + // var textarea = document.getElementById("Log"); + // textarea.value += log + "\n"; + // textarea.scrollTop = textarea.scrollHeight; + } + + //#endregion +} diff --git a/src/script/BJ_Casino_Magnification.ts b/src/script/BJ_Casino_Magnification.ts new file mode 100644 index 0000000..ea7b414 --- /dev/null +++ b/src/script/BJ_Casino_Magnification.ts @@ -0,0 +1,49 @@ +import { BJ_Casino_Data } from "./BJ_Casino_Data"; +import { Tools } from "./Tools"; + +export class BJ_Casino_Magnification { + //#region Lifecycle + + public BJ_Casino: BJ_Casino_Data | undefined; + + //#endregion + + //#region private + + private _client: any; + + //#endregion + + //#region Lifecycle + + /** + * + */ + constructor(client: any) { + this._client = client; + this.BJ_Casino = client.BJ_Casino; + this.onLoad(); + } + + public async onLoad() { + await this.SetInit(); + }; + + public async SetInit() { + while (this.BJ_Casino?.Client.isLoading.value) { + await Tools.Sleep(50); + } + this._client.Title.value = this.BJ_Casino?.Title; + this.SendData(); + }; + + //#endregion + + //#region Custom + + public SendData() { + this._client.RankData.value = this.BJ_Casino?.RankMagnificationData; + } + + //#endregion +} diff --git a/src/script/BJ_Casino_UserData.ts b/src/script/BJ_Casino_UserData.ts new file mode 100644 index 0000000..d300f57 --- /dev/null +++ b/src/script/BJ_Casino_UserData.ts @@ -0,0 +1,27 @@ +export class BJ_Casino_UserData { + //#region public + + public AID: string = ""; + + public NickName: string = ""; + + public Money: number = 0; + + public Level: number = 0; + + public Exp: number = 0; + + //#endregion + + //#region Lifecycle + + constructor(aid: string, nickName: string, money: number, level: number, exp: number) { + this.AID = aid; + this.NickName = nickName; + this.Money = money; + this.Level = level; + this.Exp = exp; + } + + //#endregion +} diff --git a/src/script/BJ_Casino_WinMoney.ts b/src/script/BJ_Casino_WinMoney.ts new file mode 100644 index 0000000..87a9a5d --- /dev/null +++ b/src/script/BJ_Casino_WinMoney.ts @@ -0,0 +1,49 @@ +import { BJ_Casino_Data } from "./BJ_Casino_Data"; +import { Tools } from "./Tools"; + +export class BJ_Casino_WinMoney { + //#region Lifecycle + + public BJ_Casino: BJ_Casino_Data | undefined; + + //#endregion + + //#region private + + private _client: any; + + //#endregion + + //#region Lifecycle + + /** + * + */ + constructor(client: any) { + this._client = client; + this.BJ_Casino = client.BJ_Casino; + this.onLoad(); + } + + public async onLoad() { + await this.SetInit(); + }; + + public async SetInit() { + while (this.BJ_Casino?.Client.isLoading.value) { + await Tools.Sleep(50); + } + this._client.Title.value = this.BJ_Casino?.Title; + this.SendData(); + }; + + //#endregion + + //#region Custom + + public SendData() { + this._client.RankData.value = this.BJ_Casino?.RankWinMoneyData; + } + + //#endregion +} diff --git a/src/script/Base/BusinessTypeSetting.ts b/src/script/Base/BusinessTypeSetting.ts new file mode 100644 index 0000000..ec08773 --- /dev/null +++ b/src/script/Base/BusinessTypeSetting.ts @@ -0,0 +1,237 @@ +export module BusinessEnum { + export enum BusinessType { + Type1 = "H5", + Type2 = "App" + } + export enum ServerType { + /** WEB格式 */ + Web = 1, + /** 外版 */ + Out = 2, + /** 送審環境 */ + Submit = 3, + /** 內版商業DEMO測試(B2B) */ + Internal_release = 4, + /** 內版開發(內網&4G) */ + Internal_Dev = 5, + /** 外部商業DEMO(B2B) */ + Out_B2B = 6 + } + export enum LogoType { + /** 完美(目前只有WEB) */ + WM = 1 + } +} + +/** +產品商業類別設定檔 +@explain 讀不同表就代表不同商業類別.要多開GIT並設定新測試環境 +@explain 遊戲一定都一樣不能改動介面 + */ +export default class BusinessTypeSetting { + /** 產品商業類別字串(組合判斷用) */ + public static readonly TYPE_BUSINESS: string = "App"; + /** 編譯版本 */ + public static readonly COMPILE_VERSION: string = "1.4.1"; + /** 編譯程式碼版號 */ + public static readonly SCRIPT_BUNLE_LIST: string[] = [ + "FormTableScript", "CommonScript", "ElementUIScript", "LoginScript", "LobbyScript", "SlotScript" + ]; + public static readonly ART_UI_BUNLE_LIST: string[] = [ + "Common", "CommonSound", "Login", "Lobby", "GameCommon", + "Game_BottomUI_SD", "Game_BigWinJackpot", "GameMessage", "CommonLanguageTexture", "MainControl", + "BindAccount", "SettingPanel", "Shop", "Vip", "Ad", + "Mail", "Chat", "PlayerInfo", "Rank", "Gift", + "ResourceItem", "Backpack", "GettingPanel", "Activity", "Game_BottomUI_BJ" + ]; + public static readonly DEV_ART_UI_BUNLE_LIST: string[] = [ + + ] + public static readonly ART_GAME_BUNLE_LIST: string[] = [ + "Game_1201", "Game_1202", "Game_1302" + ] + public static readonly ART_REMOTE_GAME_BUNLE_LIST: string[] = [ + "Game_1", "Game_2", "Game_5", "Game_8", "Game_9", + "Game_10", "Game_12", "Game_15", "Game_16", "Game_18", + "Game_23", "Game_24", "Game_25", "Game_26", "Game_27", + "Game_28", "Game_29", "Game_30", "Game_32", "Game_33", + "Game_34", "Game_35", "Game_37", "Game_36", "Game_40", + "Game_44", "Game_48", "Game_50", "Game_51", "Game_58", + "Game_1101", "Game_1401", "Game_1501", "Game_2001", "Game_2003", + "Game_3002", "Game_3003", "Game_3012", + ] + /** 送審旗標(讀取外版自動判斷是否送審) */ + public static IsSubmit: boolean = false; + /** 跑送審2的手動旗標(若是送審且設為true跑2號環境) */ + public static IsSubmitTestFlight: boolean = false; + /** B2B手動旗標(true寫死B2B環境) */ + public static IsB2B: boolean = false; + + /** 商業LOGO圖代碼(讀同一張表但UI有改的設定) */ + public static Logo: number = null!; + /** 連線IP(網頁版會接網址參數所以要多開變數直接指定) */ + public static UseHost: string = null!; + /** 連接阜(網頁版會接網址參數所以要多開變數直接指定) */ + public static UsePort: number = null!; + /** 資源伺服器網址 */ + public static UsePatch: string = null!; + /** 帳號 */ + public static Account: string = null!; + /** 密碼 */ + public static Password: string = null!; + + // ======================================================================================= + /** 執行環境ProductEnum.ServerType */ + public static UseServerTpye: BusinessEnum.ServerType = BusinessEnum.ServerType.Web; + /** 網頁是否在伺服器上 */ + public static readonly CheckOnServer: boolean = + window.location.href.indexOf("localhost") == -1 + && window.location.href.indexOf("/build/") == -1; + /** 網頁測試讀取對應資源的位置 */ + public static readonly FolderUrlImg: string = "shared/img/"; + public static readonly FolderUrlBg: string = "shared/bg/"; + public static readonly FolderUrlJson: string = "shared/jsons/"; + public static readonly FolderUrlTxt: string = "shared/txt/"; + public static readonly FolderUrlLoading: string = "shared/loading/"; + public static readonly FolderUrlMp3: string = "shared/"; + public static readonly FolderUrlBundle: string = `Bundle_${true ? "Debug" : "Release"}/`; + public static readonly FolderOS: string = "Android/"; + /**遠端Bundle路徑為: URL + BundleName.非遊戲資源到各自平台資料夾找BUNDLE */ + public static GetRemoteFileUrl(bundleName: string): string { + let gameNumber: string = bundleName.split("Game_")[1]; + var regExp: RegExp = /^[0-9]+$/; + let isGame: boolean = regExp.test(gameNumber); + let bundleUrl: string = `${BusinessTypeSetting.UsePatch}${BusinessTypeSetting.FolderUrlBundle}`; + if (isGame) { + bundleUrl = `${bundleUrl}${bundleName}`; + } else { + bundleUrl = `${bundleUrl}${BusinessTypeSetting.FolderOS}${bundleName}`; + } + return bundleUrl; + } + /** + * 取得PACH資原路徑 + * @param type 執行環境() + * @returns + */ + public static GetPatchUrl(type: BusinessEnum.ServerType): string { + if (this.UseServerTpye == BusinessEnum.ServerType.Web) { + // TYP2網頁版資源路路徑判斷 + if (this.CheckOnServer) { + return "../shared/"; + } else { + return "http://patch-dev.online-bj.com//shared/"; + } + } + switch (type) { + case BusinessEnum.ServerType.Out: + return "https://patch.online-bj.com/game/"; + case BusinessEnum.ServerType.Submit: + if (!this.IsSubmitTestFlight) { + return "https://patch-submit.online-bj.com/game/"; + } else { + return "https://patch-submit2.online-bj.com/game/"; + } + + case BusinessEnum.ServerType.Out_B2B: + return "https://patch-demo.online-bj.com/game/"; + case BusinessEnum.ServerType.Internal_release: + return "http://patch-release.online-bj.com/"; + + case BusinessEnum.ServerType.Internal_Dev: + return "http://patch-dev.online-bj.com/"; + + default: + console.warn("GetPatchUrl Uncheck ServerType."); + return "http://patch-dev.online-bj.com/"; + } + } + /** + * 取得連線伺服器IP + * @param type 執行環境 + * @returns + */ + public static GetHostUrl(type: BusinessEnum.ServerType): string { + if (this.UseServerTpye == BusinessEnum.ServerType.Web) { + return "app.casino.catan.com.tw"; + } + switch (type) { + case BusinessEnum.ServerType.Out: + return "https://game.online-bj.com"; + case BusinessEnum.ServerType.Submit: + if (!this.IsSubmitTestFlight) { + return "https://submit.online-bj.com"; + } else { + return "https://submit2.online-bj.com"; + } + + case BusinessEnum.ServerType.Out_B2B: + return "https://demo.online-bj.com"; + case BusinessEnum.ServerType.Internal_release: + return "https://demo.online-bj.com"; + + case BusinessEnum.ServerType.Internal_Dev: + return "http://220.134.195.1"; + + default: + console.warn("GetHostUrl Uncheck ServerType."); + // 只有內網可憐IP + return "app.casino.catan.com.tw"; + } + } + /** + * 取得伺服器連接端口 + * @param type 執行環境 + * @returns + */ + public static GetPortNum(type: BusinessEnum.ServerType): number { + if (this.UseServerTpye == BusinessEnum.ServerType.Web) { + // 網頁版測試專用.正式接網頁參數 + return 9005; + } + switch (type) { + case BusinessEnum.ServerType.Out: + return 9005; + case BusinessEnum.ServerType.Submit: + if (!this.IsSubmitTestFlight) { + return 9005; + } else { + return 9005; + } + + case BusinessEnum.ServerType.Out_B2B: + return 9005; + case BusinessEnum.ServerType.Internal_release: + return 9005; + + case BusinessEnum.ServerType.Internal_Dev: + return 19005; + + default: + console.warn("GePortNum Uncheck ServerType."); + return 9005; + } + } + public static GetDownloadUrl(type: BusinessEnum.ServerType): string { + switch (type) { + case BusinessEnum.ServerType.Internal_Dev: + return "http://static-dev.online-bj.com/"; + default: + let url: string = this.GetHostUrl(type); + url = url.replace("http://", ""); + url = url.replace("https://", ""); + return "https://static-" + url; + } + } + + public static GetUploadUrl(type: BusinessEnum.ServerType): string { + let port: string = ":9080"; + switch (type) { + case BusinessEnum.ServerType.Internal_Dev: + return "http://static-dev.online-bj.com" + port; + default: + return this.GetHostUrl(type) + port; + } + } + // ======================================================================================= +} \ No newline at end of file diff --git a/src/script/Base/CSMessage.ts b/src/script/Base/CSMessage.ts new file mode 100644 index 0000000..bd8c1f9 --- /dev/null +++ b/src/script/Base/CSMessage.ts @@ -0,0 +1,8 @@ +/**訊息框相關 */ +export default class CSMessage { + /**網路錯誤訊息 */ + public static NetError(method: string, state: number, str: string = ""): void { + let error = String.Format("[{0}] state:{1} {2}", method, state, str); + console.warn("網路錯誤訊息: ", error); + } +} \ No newline at end of file diff --git a/src/script/Base/Config.ts b/src/script/Base/Config.ts new file mode 100644 index 0000000..21af188 --- /dev/null +++ b/src/script/Base/Config.ts @@ -0,0 +1,22 @@ +/**放跟ProductSetting沒關係的變數 */ +export default class Config { + /**是否是連線模式 */ + public static IsOnlineMode: boolean = false; + /**內版帳號登入(目前只支援TYPE1.請從GM工具創好帳號在去DEMO場景加按鈕) */ + public static IsDemoLogin: boolean = false; + /**遊戲模式(0一般 1特色.WEB才有分) */ + public static GameMode: number = 0; + /**顯示金錢變動LOG */ + public static ShowMoneyLog: boolean = true; + /**顯示測試畫面 */ + public static ShowTest: boolean = false; + public static GetRunDevice(): number { + return 0; + } + public static IsANDROID(): boolean { + return false; + } + public static IsIOS(): boolean { + return false; + } +} diff --git a/src/script/Base/Request/AccountRequest.ts b/src/script/Base/Request/AccountRequest.ts new file mode 100644 index 0000000..d50afe2 --- /dev/null +++ b/src/script/Base/Request/AccountRequest.ts @@ -0,0 +1,237 @@ +import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest"; +import BusinessTypeSetting from "../BusinessTypeSetting"; +import Config from "../Config"; + +// ======================================================================================= +/** 通用回傳SERVER創的帳號 */ +interface CommonAccountResponse { + a: string; + pw: string; +} + +// ======================================================================================= +interface CreateResquest { + p: number; +} +/** 直接玩(訪客給SERVER創帳號) */ +export class AccountCreateRequest extends NetRequest { + get Method(): string { + return "account.create"; + } + constructor() { + super(); + this.Data = { + p: Config.GetRunDevice(), + }; + } +} +// ======================================================================================= +interface LoginResquest { + p: number; + device_info: string[]; + fcm_token: string; + a: string; + pw: string; + ver: string; +} +interface LoginResponse { + pr: string; + cu: string; +} +/** 通用登入 */ +export class AccountLoginRequest extends NetRequest { + get Method(): string { + return "account.login"; + } + constructor(account: string, password: string) { + super(); + this.Data = { + p: Config.GetRunDevice(), + device_info: ["Windows", "Windows"], + fcm_token: "", + a: account, + pw: password, + ver: BusinessTypeSetting.COMPILE_VERSION + }; + } +} +// ======================================================================================= +interface CustomResquest { + a: string; + pw: string; +} +/** 自定帳號榜定 */ +export class CustomBindRequest extends NetRequest { + get Method(): string { + return "register.account_bind"; + } + constructor(account: string, password: string) { + super(); + this.Data = { + a: account, + pw: password, + }; + } +} +/** 自定帳號登入(回傳SERVER帳號) */ +export class CustomLoginRequest extends NetRequest { + get Method(): string { + return "register.account_login"; + } + constructor(account: string, password: string) { + super(); + this.Data = { + a: account, + pw: password, + }; + } +} +// ======================================================================================= +interface FBResquest { + t: string; +} +/** FB綁定 */ +export class FBBindRequest extends NetRequest { + get Method(): string { + return "register.fb_bind"; + } + constructor(token: string) { + super(); + this.Data = { + t: token, + }; + } +} +/** FB登入(回傳SERVER帳號) */ +export class FBLoginRequest extends NetRequest { + get Method(): string { + return "register.fb_login"; + } + constructor(token: string) { + super(); + this.Data = { + t: token, + }; + } +} +// ======================================================================================= +interface GoogleResquest { + c: string; +} +/** GOOGLE綁定 */ +export class GoogleBindRequest extends NetRequest { + get Method(): string { + return "register.google_bind"; + } + constructor(token: string) { + super(); + this.Data = { + c: token, + }; + } +} +/** GOOGLE登入(回傳SERVER帳號) */ +export class GoogleLoginRequest extends NetRequest { + get Method(): string { + return "register.google_login"; + } + constructor(token: string) { + super(); + this.Data = { + c: token, + }; + } +} +// ======================================================================================= +interface AppleResquest { + c: string; +} +/** APPEL綁定 */ +export class AppleBindRequest extends NetRequest { + get Method(): string { + return "register.apple_bind"; + } + constructor(token: string) { + super(); + this.Data = { + c: token, + }; + } +} +/** APPLE登入(回傳SERVER帳號) */ +export class AppleLoginRequest extends NetRequest { + get Method(): string { + return "register.apple_login"; + } + constructor(token: string) { + super(); + this.Data = { + c: token, + }; + } +} +// ======================================================================================= +/** 電話驗證 */ +export interface PhoneCodeRequest { + p: string; +} + +export class PhoneGet extends NetRequest { + get Method(): string { + return "register.phone_code"; + } + constructor(p: string) { + super(); + this.Data = { + p: p + }; + } +} + +export interface PhoneBindRequest { + c: string; +} + +export class PhoneBind extends NetRequest { + get Method(): string { + return "register.phone_bind"; + } + constructor(c: string) { + super(); + this.Data = { + c: c + }; + } +} + +// ======================================================================================= +/** 旗標更新 */ +export class FlagOpenAdd extends NetRequest { + get Method(): string { + return "flag.open_add"; + } + constructor(type: number) { + super(); + this.Data = type; + } +} + +// ======================================================================================== +export interface ForgotInfo { + a: string; + p: string; +} + +/** 忘記密碼 */ +export class ForgotPassword extends NetRequest { + get Method(): string { + return "register.account_forget"; + } + constructor(account: string, phone: string) { + super(); + this.Data = { + a: account, + p: phone, + }; + } +} \ No newline at end of file diff --git a/src/script/Base/Request/RankRequest.ts b/src/script/Base/Request/RankRequest.ts new file mode 100644 index 0000000..382d060 --- /dev/null +++ b/src/script/Base/Request/RankRequest.ts @@ -0,0 +1,72 @@ +import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest"; + +export interface RankInfo { + t: number; + p?: number; + id?: number; +} + +export class AppRankInfo extends NetRequest { + get Method(): string { + return "rank.info"; + } + constructor(Type: number, Parameter?: number) { + super(); + this.Data = { + t: Type, + p: Parameter, + }; + } +} + +export class AppRankHistory extends NetRequest { + get Method(): string { + return "rank.history"; + } + constructor(Type: number, Parameter: number, DayId: number) { + super(); + this.Data = { + id: DayId, + t: Type, + p: Parameter + }; + } +} + +export interface RankReplayInfo { + id: number; + t: number; + r: number; + p: number; +} + + +export class AppRankLog extends NetRequest { + get Method(): string { + return "rank.log"; + } + constructor(DayId: number, Type: number, rank: number, Parameter: number) { + super(); + this.Data = { + id: DayId, + t: Type, + r: rank, + p: Parameter + }; + } +} + +export class TestAppRankLog extends NetRequest { + get Method(): string { + return "rank.log_test"; + } + constructor(DayId: number, Type: number, rank: number, Parameter: number) { + super(); + this.Data = { + id: DayId, + t: Type, + r: rank, + p: Parameter + }; + } +} \ No newline at end of file diff --git a/src/script/Common/ChooseSeat/ChooseSeatRequest.ts b/src/script/Common/ChooseSeat/ChooseSeatRequest.ts new file mode 100644 index 0000000..3f54e67 --- /dev/null +++ b/src/script/Common/ChooseSeat/ChooseSeatRequest.ts @@ -0,0 +1,51 @@ +import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest"; + + +interface SeatListResquest { + hall: number; + slot: number; +} +/** 機台所有座位 */ +export class SeatListRequest extends NetRequest { + get Method(): string { + return "seat.list"; + } + constructor(HallType: number, SlotID: number) { + super(); + this.Data = { + hall: HallType, + slot: SlotID + }; + } +} + +interface SeatInfoResquest { + hall: number; + slot: number; + id: number; +} + +/** 獨立座位資料 */ +export class SeatInfoRequest extends NetRequest { + get Method(): string { + return "seat.info"; + } + constructor(HallType: number, SlotID: number, ID: number) { + super(); + this.Data = { + hall: HallType, + slot: SlotID, + id: ID + }; + } +} + +/** 機台佔用 */ +export class SeatOccupy extends NetRequest { + get Method(): string { + return "seat.occupy"; + } + constructor() { + super(); + } +} \ No newline at end of file diff --git a/src/script/Common/Subgame/GameRequest.ts b/src/script/Common/Subgame/GameRequest.ts new file mode 100644 index 0000000..f615131 --- /dev/null +++ b/src/script/Common/Subgame/GameRequest.ts @@ -0,0 +1,69 @@ +import BusinessTypeSetting, { BusinessEnum } from "../../Base/BusinessTypeSetting"; +import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest"; + +//======================================================================================= +// /**取得歷史紀錄網頁網址協定 */ +// export class HistoryRequest extends NetRequest { +// get Method(): string { +// return "history.url"; +// } + +// constructor(slotId: number) { +// super(); +// this.Data = { +// slot: slotId, +// lang: LanguageManager.UseLanguageUrlStr, +// }; +// } +// } +//======================================================================================= +export class SlotInRequest extends NetRequest { + get Method(): string { + return "slot.in"; + } + constructor(slotid: number, hall: number = 0, uid: number = 0) { + super(); + switch (BusinessTypeSetting.TYPE_BUSINESS) { + case BusinessEnum.BusinessType.Type1: + this.Data = { + id: slotid + } + break; + case BusinessEnum.BusinessType.Type2: + this.Data = { + id: slotid, + hall: hall, + uid: uid, + }; + break; + default: + console.error("No TYPE_BUSINESS"); + break; + } + } +} +//======================================================================================= +export class SlotOutRequest extends NetRequest { + get Method(): string { + return "slot.out"; + } +} +//======================================================================================= +export class FishOutRequest extends NetRequest { + get Method(): string { + return "fish.out"; + } +} +//======================================================================================= +export class TableOutRequest extends NetRequest { + get Method(): string { + return "table.out"; + } +} +//======================================================================================= +export class PinBallOutRequest extends NetRequest { + get Method(): string { + return "pinball.out"; + } +} +//======================================================================================= diff --git a/src/script/Engine/CatanEngine.meta b/src/script/Engine/CatanEngine.meta new file mode 100644 index 0000000..f0d308f --- /dev/null +++ b/src/script/Engine/CatanEngine.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "a69fe64f-177f-4e4b-83f0-1f418203d85f", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp.meta b/src/script/Engine/CatanEngine/CSharp.meta new file mode 100644 index 0000000..ad81719 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "f9edb32f-c4ab-4e5d-8270-71fa609e1db7", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/String.ts b/src/script/Engine/CatanEngine/CSharp/String.ts new file mode 100644 index 0000000..b2022dd --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/String.ts @@ -0,0 +1,20 @@ +declare global { + interface StringConstructor { + IsNullOrEmpty: (value: string) => boolean; + Format: (format: string, ...args: any[]) => string; + } +} + +String.IsNullOrEmpty = function (value: string): boolean { + return value === undefined || value === null || value.trim() === ''; +}; + +String.Format = function (format: string, ...args: any[]): string { + return format.replace(/{(\d+)}/g, (match, index) => { + let value = args[index]; + if (value === null || value === undefined) return ''; + return '' + value; + }); +} + +export { }; diff --git a/src/script/Engine/CatanEngine/CSharp/String.ts.meta b/src/script/Engine/CatanEngine/CSharp/String.ts.meta new file mode 100644 index 0000000..42955f2 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/String.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "0c3d1ca6-bdaf-4a00-b209-6ef460802cdc", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System.meta b/src/script/Engine/CatanEngine/CSharp/System.meta new file mode 100644 index 0000000..4b20ca4 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "01b35dee-e6e0-4a6e-a73c-3b49c37f1c5f", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/Action.ts b/src/script/Engine/CatanEngine/CSharp/System/Action.ts new file mode 100644 index 0000000..d00d7cf --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/Action.ts @@ -0,0 +1,125 @@ +/** + * 回呼函數: fnname (arg: TArg): void + */ +interface ActionCallback { + (arg: TArg): void; +} + +interface Struct { + callback: ActionCallback; + target: any; + once?: boolean; +} + +export class Action { + private _queue: Struct[] = []; + + /** + * 監聽事件 + * @param callback 回呼函數: fnname (arg: TArg): void + * @param bindTarget 回呼時this綁定的對象 + */ + AddCallback(callback: ActionCallback, bindTarget?: any) { + let q = > { + callback: callback, + target: bindTarget + }; + this._queue.push(q); + } + + /** + * 監聽事件 (一次性) + * @param callback 回呼函數: fnname (arg: TArg): void + * @param bindTarget 回呼時this綁定的對象 + */ + AddCallbackOnce(callback: ActionCallback, bindTarget?: any) { + let q = > { + callback: callback, + target: bindTarget, + once: true + }; + this._queue.push(q); + } + + /** + * 移除事件 + * @param callback + */ + RemoveByCallback(callback: ActionCallback) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.callback === callback) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除事件 + * @param bindTarget 回呼時this綁定的對象 + */ + RemoveByBindTarget(bindTarget: any) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.target === bindTarget) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除全部事件 + */ + RemoveAllCallbacks() { + this._queue.forEach(q => q.callback = undefined); + this._queue.length = 0; + } + + /** + * 發送事件 + * @param arg 參數 + */ + DispatchCallback(arg: TArg) { + let index = this._queue.length; + if (index > 0) { + let cleanRemoved = false; + this._queue.slice().forEach(q => { + if (!q.callback) { + cleanRemoved = true; + return; + } + + if (q.target) { + q.callback.call(q.target, arg); + } else { + q.callback(arg); + } + + if (q.once) { + q.callback = undefined; + cleanRemoved = true; + } + }); + + if (cleanRemoved) { + index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback) { + this._queue.splice(index, 1); + } + } + } + } + } + } +} diff --git a/src/script/Engine/CatanEngine/CSharp/System/Action.ts.meta b/src/script/Engine/CatanEngine/CSharp/System/Action.ts.meta new file mode 100644 index 0000000..a62a428 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/Action.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "ea9bf762-40a7-4bab-b949-8d5b3d4289e2", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts b/src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts new file mode 100644 index 0000000..7ab459a --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts @@ -0,0 +1,85 @@ +import { Action } from "./Action"; +import { ActionWithType } from "./ActionWithType"; +import { ActionWithType2 } from "./ActionWithType2"; + +const { ccclass, property } = console._decorator; + +enum CustomType { + Ex1, Ex2 +} + +class CustomEvent extends ActionWithType { } +class CustomEvent2 extends ActionWithType2 { } + +@ccclass +export default class NewClass extends console.Component { + callback: Action = new Action(); + customCallback: CustomEvent = new CustomEvent(); + customCallback2: CustomEvent2 = new CustomEvent2(); + + private num: number = 0; + + start() { + this.callback.AddCallback(this.CB, this); + this.callback.AddCallbackOnce(this.OnceCB, this); + + this.customCallback.AddCallback(CustomType.Ex1, this.CBType, this); + this.customCallback.AddCallbackOnce(CustomType.Ex2, this.OnceCBType, this); + + this.customCallback2.AddCallback(CustomType.Ex2, this.CBTypeAllin1, this); + this.customCallback2.AddCallbackOnce(CustomType.Ex1, this.CBTypeAllin1, this); + } + + DispatchClick() { + this.num++; + + this.callback.DispatchCallback(this.num); + + this.customCallback.DispatchCallback(CustomType.Ex1, this.num); + this.customCallback.DispatchCallback(CustomType.Ex2, this.num); + + this.customCallback2.DispatchCallback(CustomType.Ex1, this.num); + this.customCallback2.DispatchCallback(CustomType.Ex2, this.num); + } + + RemoveEventClick() { + this.callback.RemoveByCallback(this.CB); + // this.callback.RemoveByCallback(this.OnceCB); + // this.callback.RemoveByBindTarget(this); + // this.callback.RemoveAll(); + + // this.callbackWithType.RemoveByCallback(this.CBType); + // this.callbackWithType.RemoveByCallback(this.OnceCBType); + this.customCallback.RemoveByType(CustomType.Ex1); + // this.callbackWithType.RemoveByType(CustomType.Ex2); + // this.callbackWithType.RemoveByBindTarget(this); + // this.callbackWithType.RemoveAll(); + } + + OnceCB(x: number) { + console.log(`OnceCB [${this.num}]`); + } + + CB(x: number) { + console.log(`CB [${this.num}]`); + } + + OnceCBType(x: number) { + console.log(`OnceCBType [${this.num}]`); + } + + CBType(x: number) { + console.log(`CBType [${this.num}]`); + } + + CBTypeAllin1(type: CustomType, x: number) { + // switch (type) { + // case CustomType.Ex1: + // break; + // case CustomType.Ex2: + // break; + // } + + console.log(`CBTypeAllin1 [${CustomType[type]}][${this.num}]`); + } +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts.meta b/src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts.meta new file mode 100644 index 0000000..b2e8b66 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "cc645b73-6192-414d-a5bc-4220c24e322d", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts new file mode 100644 index 0000000..81248da --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts @@ -0,0 +1,166 @@ +/** + * 回呼函數: fnname (arg: TArg): void + */ +interface ActionCallback { + (arg: TArg): void; +} + +interface Struct { + callback: ActionCallback; + target: any; + type: TType; + once?: boolean; +} + +export class ActionWithType { + private _queue: Struct[] = []; + + /** + * 監聽事件 + * @param callback 回呼函數: fnname (arg: TArg): void + * @param bindTarget 回呼時this綁定的對象 + */ + AddCallback(type: TType, callback: ActionCallback, bindTarget?: any) { + let q = > { + callback: callback, + target: bindTarget, + type: type + }; + this._queue.push(q); + } + + /** + * 監聽事件 (一次性) + * @param callback 回呼函數: fnname (arg: TArg): void + * @param bindTarget 回呼時this綁定的對象 + */ + AddCallbackOnce(type: TType, callback: ActionCallback, bindTarget?: any) { + let q = > { + callback: callback, + target: bindTarget, + type: type, + once: true + }; + this._queue.push(q); + } + + /** + * 移除事件 + * @param callback + */ + RemoveByCallback(callback: ActionCallback) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.callback === callback) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除事件 + * @param bindTarget 回呼時this綁定的對象 + */ + RemoveByBindTarget(bindTarget: any) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.target === bindTarget) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除事件 + * @param type 事件類型 + */ + RemoveByType(type: TType) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.type === type) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除事件 + * @param type 事件類型 + * @param callback + */ + RemoveCallback(type:TType, callback: ActionCallback) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || (q.type === type && q.callback === callback)) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除全部事件 + */ + RemoveAllCallbacks() { + this._queue.forEach(q => q.callback = undefined); + this._queue.length = 0; + } + + /** + * 發送事件 + * @param type 事件類型 + * @param arg 參數 + */ + DispatchCallback(type: TType, arg: TArg) { + let index = this._queue.length; + if (index > 0) { + let cleanRemoved = false; + this._queue.slice().forEach(q => { + if (!q.callback) + { + cleanRemoved = true; + return; + } + if (q.type !== type) return; + + if (q.target) { + q.callback.call(q.target, arg); + } else { + q.callback(arg); + } + + if (q.once) { + q.callback = undefined; + cleanRemoved = true; + } + }); + + if (cleanRemoved) { + index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback) { + this._queue.splice(index, 1); + } + } + } + } + } + } +} diff --git a/src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts.meta b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts.meta new file mode 100644 index 0000000..e1e3d30 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "61d770ec-24e2-425b-b66b-2b03e192e45b", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts new file mode 100644 index 0000000..1b68673 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts @@ -0,0 +1,166 @@ +/** + * 回呼函數: fnname (type: TType, arg: TArg): void + */ +interface ActionCallback { + (type: TType, arg: TArg): void; +} + +interface Struct { + callback: ActionCallback; + target: any; + type: TType; + once?: boolean; +} + +export class ActionWithType2 { + private _queue: Struct[] = []; + + /** + * 監聽事件 + * @param callback 回呼函數: fnname (type: TType, arg: TArg): void + * @param bindTarget 回呼時this綁定的對象 + */ + AddCallback(type: TType, callback: ActionCallback, bindTarget?: any) { + let q = > { + callback: callback, + target: bindTarget, + type: type + }; + this._queue.push(q); + } + + /** + * 監聽事件 (一次性) + * @param callback 回呼函數: fnname (type: TType, arg: TArg): void + * @param bindTarget 回呼時this綁定的對象 + */ + AddCallbackOnce(type: TType, callback: ActionCallback, bindTarget?: any) { + let q = > { + callback: callback, + target: bindTarget, + type: type, + once: true + }; + this._queue.push(q); + } + + /** + * 移除事件 + * @param callback + */ + RemoveByCallback(callback: ActionCallback) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.callback === callback) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除事件 + * @param bindTarget 回呼時this綁定的對象 + */ + RemoveByBindTarget(bindTarget: any) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.target === bindTarget) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除事件 + * @param type 事件類型 + */ + RemoveByType(type: TType) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || q.type === type) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除事件 + * @param type 事件類型 + * @param callback + */ + RemoveCallback(type:TType, callback: ActionCallback) { + let index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback || (q.type === type && q.callback === callback)) { + q.callback = undefined; + this._queue.splice(index, 1); + } + } + } + } + + /** + * 移除全部事件 + */ + RemoveAllCallbacks() { + this._queue.forEach(q => q.callback = undefined); + this._queue.length = 0; + } + + /** + * 發送事件 + * @param type 事件類型 + * @param arg 參數 + */ + DispatchCallback(type: TType, arg: TArg) { + let index = this._queue.length; + if (index > 0) { + let cleanRemoved = false; + this._queue.slice().forEach(q => { + if (!q.callback) + { + cleanRemoved = true; + return; + } + if (q.type !== type) return; + + if (q.target) { + q.callback.call(q.target, type, arg); + } else { + q.callback(type, arg); + } + + if (q.once) { + q.callback = undefined; + cleanRemoved = true; + } + }); + + if (cleanRemoved) { + index = this._queue.length; + if (index > 0) { + while (index--) { + let q = this._queue[index]; + if (!q.callback) { + this._queue.splice(index, 1); + } + } + } + } + } + } +} diff --git a/src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts.meta b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts.meta new file mode 100644 index 0000000..a37aa2c --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "ed703ebd-efd4-4ec9-9b84-de748ef8f9e8", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/Text.meta b/src/script/Engine/CatanEngine/CSharp/System/Text.meta new file mode 100644 index 0000000..7e3f112 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/Text.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "09d69d12-a6d1-4bb1-bcfe-faa811632467", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts b/src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts new file mode 100644 index 0000000..dc39cf8 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts @@ -0,0 +1,68 @@ +export module Encoding.UTF8 { + + export function GetBytes(str: string) { + let len = str.length, resPos = -1; + let resArr = new Uint8Array(len * 3); + for (let point = 0, nextcode = 0, i = 0; i !== len; ) { + point = str.charCodeAt(i), i += 1; + if (point >= 0xD800 && point <= 0xDBFF) { + if (i === len) { + resArr[resPos += 1] = 0xef; + resArr[resPos += 1] = 0xbf; + resArr[resPos += 1] = 0xbd; + break; + } + + nextcode = str.charCodeAt(i); + if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) { + point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000; + i += 1; + if (point > 0xffff) { + resArr[resPos += 1] = (0x1e << 3) | (point >>> 18); + resArr[resPos += 1] = (0x2 << 6) | ((point >>> 12) & 0x3f); + resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f); + resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); + continue; + } + } else { + resArr[resPos += 1] = 0xef; + resArr[resPos += 1] = 0xbf; + resArr[resPos += 1] = 0xbd; + continue; + } + } + if (point <= 0x007f) { + resArr[resPos += 1] = (0x0 << 7) | point; + } else if (point <= 0x07ff) { + resArr[resPos += 1] = (0x6 << 5) | (point >>> 6); + resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); + } else { + resArr[resPos += 1] = (0xe << 4) | (point >>> 12); + resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f); + resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); + } + } + return resArr.subarray(0, resPos + 1); + } + + export function GetString(array: Uint8Array) { + let str = ""; + let i = 0, len = array.length; + while(i < len) { + let c = array[i++]; + switch (c >> 4) + { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + str += String.fromCharCode(c); + break; + case 12: case 13: + str += String.fromCharCode(((c & 0x1F) << 6) | (array[i++] & 0x3F)); + break; + case 14: + str += String.fromCharCode(((c & 0x0F) << 12) | ((array[i++] & 0x3F) << 6) | ((array[i++] & 0x3F) << 0)); + break; + } + } + return str; + } +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts.meta b/src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts.meta new file mode 100644 index 0000000..02a34a1 --- /dev/null +++ b/src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "43bf5724-e939-4189-b981-c32ef694e5a5", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2.meta b/src/script/Engine/CatanEngine/CoroutineV2.meta new file mode 100644 index 0000000..4fc05bc --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "9f510f2b-83d8-4097-8683-32d6134323fb", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/CancellationTokenSource.ts b/src/script/Engine/CatanEngine/CoroutineV2/CancellationTokenSource.ts new file mode 100644 index 0000000..fe8f34e --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/CancellationTokenSource.ts @@ -0,0 +1,43 @@ +const CANCEL = Symbol(); + +export interface CancellationToken { + readonly IsCancellationRequested: boolean; + ThrowIfCancellationRequested(): void; +} + +export class CancellationTokenSource { + readonly Token: CancellationToken; + + constructor() { + this.Token = new CancellationTokenImpl(); + } + + Cancel() { + this.Token[CANCEL](); + } +} + +export class TaskCancelledException extends Error { + constructor() { + super("Task Cancelled"); + Reflect.setPrototypeOf(this, TaskCancelledException.prototype); + } +} + +class CancellationTokenImpl implements CancellationToken { + IsCancellationRequested: boolean; + + constructor() { + this.IsCancellationRequested = false; + } + + ThrowIfCancellationRequested() { + if (this.IsCancellationRequested) { + throw new TaskCancelledException(); + } + } + + [CANCEL]() { + this.IsCancellationRequested = true; + } +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/CancellationTokenSource.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/CancellationTokenSource.ts.meta new file mode 100644 index 0000000..4175ac3 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/CancellationTokenSource.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "9a414131-91a8-4d02-9921-9d1ee01764c3", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core.meta new file mode 100644 index 0000000..999a0f6 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "fbfe97a8-24ca-4f67-b049-323652c7194b", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/ActionEnumerator.ts b/src/script/Engine/CatanEngine/CoroutineV2/Core/ActionEnumerator.ts new file mode 100644 index 0000000..84c531e --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/ActionEnumerator.ts @@ -0,0 +1,17 @@ +import { BaseEnumerator } from "./BaseEnumerator"; + +export class ActionEnumerator extends BaseEnumerator { + private _action: Function; + + constructor(action: Function) { + super(); + this._action = action; + } + + next(value?: any): IteratorResult { + if (this._action) { + this._action(); + } + return { done: true, value: undefined }; + } +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/ActionEnumerator.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core/ActionEnumerator.ts.meta new file mode 100644 index 0000000..cfa8e0d --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/ActionEnumerator.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "3cf9e5c3-520f-48a9-8821-9be76d519765", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/BaseEnumerator.ts b/src/script/Engine/CatanEngine/CoroutineV2/Core/BaseEnumerator.ts new file mode 100644 index 0000000..0043213 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/BaseEnumerator.ts @@ -0,0 +1,87 @@ +import { IEnumeratorV2, IEnumeratorV2Started } from "../IEnumeratorV2"; +import { CoroutineExecutor } from "./CoroutineExecutor"; + +export abstract class BaseEnumerator implements IEnumeratorV2 { + public nextEnumerator: BaseEnumerator; + + abstract next(value?: any): IteratorResult; + + Start(target?: any): IEnumeratorV2Started { + let executor = LazyLoad.EnumeratorExecutor(this, target); + CoroutineExecutor.instance.StartCoroutine(executor); + return executor; + } + + Then(iterator: Iterator): IEnumeratorV2 { + if (!iterator) return this; + + if (iterator instanceof BaseEnumerator) { + BaseEnumerator.getLastEnumerator(this).nextEnumerator = iterator; + return this; + } else { + let enumerator = LazyLoad.SingleEnumerator(iterator); + BaseEnumerator.getLastEnumerator(this).nextEnumerator = enumerator; + return this; + } + } + + ThenSerial(...iterators: Iterator[]): IEnumeratorV2 { + let last = BaseEnumerator.getLastEnumerator(this); + for (let iterator of iterators) { + if (iterator instanceof BaseEnumerator) { + last.nextEnumerator = iterator; + } else { + let enumerator = LazyLoad.SingleEnumerator(iterator); + last.nextEnumerator = enumerator; + } + last = last.nextEnumerator; + } + return this; + } + + ThenParallel(...iterators: Iterator[]): IEnumeratorV2 { + return this.Then(LazyLoad.ParallelEnumerator(...iterators)); + } + + ThenAction(action: Function, delaySeconds?:number): IEnumeratorV2 { + if (delaySeconds > 0) { + return this.ThenSerial(LazyLoad.WaitTimeEnumerator(delaySeconds), LazyLoad.ActionEnumerator(action)); + } else { + return this.Then(LazyLoad.ActionEnumerator(action)); + } + } + + ThenWaitTime(seconds: number): IEnumeratorV2 { + return this.Then(LazyLoad.WaitTimeEnumerator(seconds)); + } + + static getLastEnumerator(enumerator: BaseEnumerator): BaseEnumerator { + let next = enumerator; + while (next.nextEnumerator) { + next = next.nextEnumerator; + } + return next; + } +} + +module LazyLoad { + export function EnumeratorExecutor(enumerator: BaseEnumerator, target: any) { + return new (require("./EnumeratorExecutor") as typeof import("./EnumeratorExecutor")).EnumeratorExecutor(enumerator, target); + } + + export function SingleEnumerator(iterator: Iterator) { + return new (require("./SingleEnumerator") as typeof import("./SingleEnumerator")).SingleEnumerator(iterator); + } + + export function ParallelEnumerator(...iterators: Iterator[]) { + return new (require("./ParallelEnumerator") as typeof import("./ParallelEnumerator")).ParallelEnumerator(iterators); + } + + export function WaitTimeEnumerator(seconds: number) { + return new (require("./WaitTimeEnumerator") as typeof import("./WaitTimeEnumerator")).WaitTimeEnumerator(seconds); + } + + export function ActionEnumerator(action: Function) { + return new (require("./ActionEnumerator") as typeof import("./ActionEnumerator")).ActionEnumerator(action); + } +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/BaseEnumerator.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core/BaseEnumerator.ts.meta new file mode 100644 index 0000000..3756fe6 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/BaseEnumerator.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "4084537c-c7e8-4d47-b283-39be77ef9685", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/CoroutineExecutor.ts b/src/script/Engine/CatanEngine/CoroutineV2/Core/CoroutineExecutor.ts new file mode 100644 index 0000000..aedf3b9 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/CoroutineExecutor.ts @@ -0,0 +1,94 @@ +import { EnumeratorExecutor } from "./EnumeratorExecutor"; + +export class CoroutineExecutor { + private static _instance: CoroutineExecutor; + static get instance() { + return CoroutineExecutor._instance = CoroutineExecutor._instance || new CoroutineExecutor(); + } + + private _executors: EnumeratorExecutor[] = []; + private _nextExecutors: EnumeratorExecutor[] = []; + private _isRunning: boolean = false; + private _cleanRemoved: boolean = false; + private _scheduler: console.Scheduler; + + constructor() { + this._scheduler = console.director.getScheduler(); + this._scheduler.enableForTarget(this); + this._scheduler.scheduleUpdate(this, 0, true); + } + + StartCoroutine(executor: EnumeratorExecutor) { + executor.next(0); + //TODO: 這邊要考量next後馬上接BaseEnumerator/Iterator的情形 + + if (!this._isRunning) { + this._executors.push(executor); + + if (this._scheduler.isTargetPaused(this)) { + this._scheduler.resumeTarget(this); + } + } else { + this._nextExecutors.push(executor); + } + } + + StopCoroutineBy(target: any) { + if (!target) return; + + for (let r of this._executors) { + if (target === r.target) { + r.Stop(); + } + } + + for (let r of this._nextExecutors) { + if (target === r.target) { + r.Stop(); + } + } + } + + update(delta: number) { + if (this._nextExecutors.length) { + this._executors.push(...this._nextExecutors); + this._nextExecutors.length = 0; + } + + if (this._cleanRemoved) { + // 移除[doneFlag=true]的協程 + let index = this._executors.length; + while (index--) { + let r = this._executors[index]; + if (r.doneFlag) { + this._executors.splice(index, 1); + } + } + this._cleanRemoved = false; + } + + if (this._executors.length == 0) { + if (true) { + console.log("[CoroutineV2] All coroutines done"); + } + this._scheduler.pauseTarget(this); + return; + } + + this._isRunning = true; + + // 執行協程 + for (let r of this._executors) { + if (r.doneFlag || r.pauseFlag || r.childFlag) { + if (r.doneFlag) { + this._cleanRemoved = true; + } + continue; + } + + r.next(delta); + } + + this._isRunning = false; + } +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/CoroutineExecutor.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core/CoroutineExecutor.ts.meta new file mode 100644 index 0000000..fc6d10b --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/CoroutineExecutor.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "f25b1e42-90d8-4fc0-9925-6e7e92296d57", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/EnumeratorExecutor.ts b/src/script/Engine/CatanEngine/CoroutineV2/Core/EnumeratorExecutor.ts new file mode 100644 index 0000000..7b7289c --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/EnumeratorExecutor.ts @@ -0,0 +1,168 @@ +import { IEnumeratorV2Started } from "../IEnumeratorV2"; +import { BaseEnumerator } from "./BaseEnumerator"; +import { SingleEnumerator } from "./SingleEnumerator"; + +export class EnumeratorExecutor implements IEnumeratorV2Started { + public Current: any; + + public target: any; + public pauseFlag: boolean; + public doneFlag: boolean; + public childFlag: boolean; + public asyncFlag: boolean; + public error: any; + + private _executor: EnumeratorExecutor; + private _enumerator: BaseEnumerator; + + constructor(enumerator: BaseEnumerator, target: any) { + this.target = target; + this._enumerator = enumerator; + } + + next(delta?: any): IteratorResult { + if (this._executor && this._executor.doneFlag) { + this._executor = null; + } + + if (this.doneFlag || (!this._enumerator && !this._executor)) { + this.doneFlag = true; + return { done: true, value: undefined }; + } + + if (this.asyncFlag || this.pauseFlag) return { done: false, value: undefined }; + + let result: IteratorResult; + + if (this._executor) { + result = this._executor.next(delta); + this.Current = this._executor.Current; + if (this._executor.doneFlag) { + this._executor = null; + } else { + result.done = false; + return result; + } + } + + if (!this._enumerator) { + this.doneFlag = true; + return { done: true, value: undefined }; + } + + try { + result = this._enumerator.next(delta); + let value = result.value; + let done = result.done; + + if (value) { + // Iterator + if (typeof value[Symbol.iterator] === 'function') { + value = new SingleEnumerator(>value); + } + + if (value instanceof BaseEnumerator) { + if (!done) { + BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator; + } + this._enumerator = value; + result = this._enumerator.next(delta); + value = result.value; + done = result.done; + + if (value) { + // Iterator again + if (typeof value[Symbol.iterator] === 'function') { + value = new SingleEnumerator(>value); + } + + if (value instanceof BaseEnumerator) { + if (!done) { + BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator; + } + this._enumerator = value; + result.done = false; + done = false; + } + } + } + + if (value instanceof EnumeratorExecutor) { + if (done) { + this._enumerator = this._enumerator.nextEnumerator; + } + value.childFlag = true; + result.done = false; + done = false; + this._executor = value; + } else if (Promise.resolve(value) === value) { + this.asyncFlag = true; + result.done = false; + done = false; + (>value) + .then(v => { + this.asyncFlag = false; + this.Current = v; + if (done) { + this._enumerator = this._enumerator.nextEnumerator; + } + }) + .catch(e => { + this.asyncFlag = false; + this.doneFlag = true; + this._enumerator = null; + this.error = e; + if (e instanceof Error) { + console.error(e.stack); + } else { + console.error(`Error: ${JSON.stringify(e)}`); + } + }); + } + + this.Current = value; + } + + if (done) { + this._enumerator = this._enumerator.nextEnumerator; + if (this._enumerator) { + result.done = false; + } + } + } + catch (e) { + this.doneFlag = true; + this.error = e; + if (e instanceof Error) { + console.error(e.stack); + } else { + console.error(`Error: ${JSON.stringify(e)}`); + } + result = { done: true, value: e }; + } + + return result; + } + + Stop(): void { + this.doneFlag = true; + if (this._executor) { + this._executor.Stop(); + } + } + + Pause(): void { + this.pauseFlag = true; + if (this._executor) { + this._executor.Pause(); + } + } + + Resume(): void { + this.pauseFlag = false; + if (this._executor) { + this._executor.Resume(); + } + } + +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/EnumeratorExecutor.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core/EnumeratorExecutor.ts.meta new file mode 100644 index 0000000..8a4b319 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/EnumeratorExecutor.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "91cb70ed-e6f9-4ce0-b7c5-1720087b3bd7", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/ParallelEnumerator.ts b/src/script/Engine/CatanEngine/CoroutineV2/Core/ParallelEnumerator.ts new file mode 100644 index 0000000..ad33439 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/ParallelEnumerator.ts @@ -0,0 +1,46 @@ +import { BaseEnumerator } from "./BaseEnumerator"; +import { EnumeratorExecutor } from "./EnumeratorExecutor"; +import { SingleEnumerator } from "./SingleEnumerator"; + +export class ParallelEnumerator extends BaseEnumerator { + private _executors: EnumeratorExecutor[] = []; + + constructor(iterators: Iterator[]) { + super(); + if (iterators && iterators.length) { + for (let iterator of iterators) { + if (iterator instanceof BaseEnumerator) { + this._executors.push(new EnumeratorExecutor(iterator, null)); + } else { + this._executors.push(new EnumeratorExecutor(new SingleEnumerator(iterator), null)); + } + } + } + } + + next(value?: any): IteratorResult { + if (this._executors.length) { + // 先移除[doneFlag=true]協程 + let index = this._executors.length; + while (index--) { + let r = this._executors[index]; + if (r.doneFlag) { + this._executors.splice(index, 1); + } + } + + if (this._executors.length == 0) { + return { done: true, value: undefined }; + } + + // 執行協程 + for (let r of this._executors) { + r.next(value); + } + + return { done: false, value: undefined }; + } + + return { done: true, value: undefined }; + } +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/ParallelEnumerator.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core/ParallelEnumerator.ts.meta new file mode 100644 index 0000000..70c1480 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/ParallelEnumerator.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "017ebc9a-5152-4f94-bbaf-e3b914e87b41", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/SingleEnumerator.ts b/src/script/Engine/CatanEngine/CoroutineV2/Core/SingleEnumerator.ts new file mode 100644 index 0000000..665a5de --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/SingleEnumerator.ts @@ -0,0 +1,18 @@ +import { BaseEnumerator } from "./BaseEnumerator"; + +export class SingleEnumerator extends BaseEnumerator { + private _iterator: Iterator; + + constructor(iterator: Iterator) { + super(); + this._iterator = iterator; + } + + next(value?: any): IteratorResult { + if (!this._iterator) { + return { done: true, value: undefined }; + } + + return this._iterator.next(value); + } +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/SingleEnumerator.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core/SingleEnumerator.ts.meta new file mode 100644 index 0000000..96ae7b1 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/SingleEnumerator.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "c439d019-2da8-48b8-a65b-bff928d0fda8", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/WaitTimeEnumerator.ts b/src/script/Engine/CatanEngine/CoroutineV2/Core/WaitTimeEnumerator.ts new file mode 100644 index 0000000..946ea29 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/WaitTimeEnumerator.ts @@ -0,0 +1,21 @@ +import { BaseEnumerator } from "./BaseEnumerator"; + +export class WaitTimeEnumerator extends BaseEnumerator { + private _seconds: number; + + constructor(seconds: number) { + super(); + this._seconds = seconds; + } + + next(value?: any): IteratorResult { + let delta = value as number; + this._seconds -= delta; + + if (this._seconds <= 0) { + return { done: true, value: 0 }; + } else { + return { done: false, value: this._seconds }; + } + } +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/Core/WaitTimeEnumerator.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/Core/WaitTimeEnumerator.ts.meta new file mode 100644 index 0000000..0572bd6 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/Core/WaitTimeEnumerator.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "a3038e6f-1bb4-4aff-a686-b69209df3592", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts new file mode 100644 index 0000000..6799204 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts @@ -0,0 +1,197 @@ +import { CoroutineV2 } from "./CoroutineV2"; +import { IEnumeratorV2Started } from "./IEnumeratorV2"; + +const { ccclass, property } = console._decorator; + +class A { + private numbers: number[] = [1, 2]; + private index = 0; + + [Symbol.iterator](): IterableIterator { + return this; + } + + next(value?: any): IteratorResult { + if (this.index < this.numbers.length) { + let value = this.numbers[this.index++]; + console.log(`A=> ${value}`); + return { + done: false, + value: value + }; + } + + return { done: true, value: undefined }; + } +} + +@ccclass +export default class CoroutineExample extends console.Component { + private _routine: IEnumeratorV2Started; + private _obj: Object = { "a": true }; + private _obj2: Object = { "b": true }; + + private _num: number = 3; + + button1Clicked() { + // this._routine = CoroutineV2 + // .Parallel(this.Coroutine1(1, 3), this.Coroutine1(4, 6)) + // .ThenWaitTime(2) + // .Then(this.Coroutine1(7, 9)) + // .ThenWaitTime(2) + // .ThenAction(() => console.log("action callback 1")) + // .ThenWaitTime(2) + // .ThenAction(this.actionCallback) + // //.Start(this); + // .Start(this); + // this._routine = CoroutineV2.Single(this.FunA()).Start(this); + + this._routine = CoroutineV2.Single(this.Test1_1()).Start(this); + // this._routine = CoroutineV2.Single(this.Test2_1()).Start(this); + } + + *Test1_1() { + yield null; + yield* this.Test1_2(); + // CoroutineV2.Single(this.Test1_3()).Start(this); + yield this.Test1_3(); + } + + *Test1_2() { + yield null; + } + + *Test1_3() { + yield this.Test1_3_1(); + yield CoroutineV2.Single(this.Test1_4()).Start(this._obj); + // yield CoroutineV2.Single(this.Test1_4()); //.Start(this); + // yield *this.Test1_4(); + console.log("main wait 3"); + yield CoroutineV2.WaitTime(2); + console.log("done"); + } + + *Test1_3_1() { + yield this.Test1_3_2(); + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_1.1"); + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_1.2"); + } + + *Test1_3_2() { + yield this.Test1_3_3(); + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_2.1"); + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_2.2"); + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_2.3"); + } + + *Test1_3_3() { + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_3.1"); + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_3.2"); + yield CoroutineV2.WaitTime(1); + console.log("Test1_3_3.3"); + } + + *Test1_4() { + this._num++; + console.log(`WaitTime2 ${this._num}`); + yield CoroutineV2.WaitTime(2).Start(this._obj2); + this._num++; + console.log(`WaitTime2 ${this._num}`); + yield CoroutineV2.WaitTime(2).Start(this._obj2); + this._num++; + console.log(`WaitTime2 ${this._num}`); + } + + *Test2_1() { + console.log("111"); + CoroutineV2.Single(this.Test2_2()).Start(this); + console.log("333"); + } + + *Test2_2() { + console.log("222"); + return; + } + + button2Clicked() { + // this._routine && this._routine.Stop(); + if (this._obj2) { + CoroutineV2.StopCoroutinesBy(this._obj2); + this._obj2 = null; + return; + } + if (this._obj) { + CoroutineV2.StopCoroutinesBy(this._obj); + this._obj = null; + return; + } + + CoroutineV2.StopCoroutinesBy(this); + + } + + button3Clicked() { + // CoroutineV2.StopCoroutinesBy(this); + this._routine && this._routine.Pause(); + } + + button4Clicked() { + // CoroutineV2.StopCoroutinesBy(this); + this._routine && this._routine.Resume(); + } + + *Coroutine1(start: number, end: number) { + for (let i = start; i <= end; i++) { + // yield CoroutineV2.WaitTime(1).Start(); // Start()可以省略, 會由外層啟動 + // yield CoroutineV2.WaitTime(1).Start(this); // target也可以省略, 由外層的target控制 + + yield CoroutineV2.WaitTime(1).Start(); + console.log(`C1 => ${i}`); + + // 嵌套 + yield CoroutineV2 + .WaitTime(1) + .ThenParallel( + // 再嵌套 + CoroutineV2.Action(() => console.log("start parallel")), + this.Coroutine2(10, 2), + this.Coroutine2(20, 2), + new A()) + .ThenAction(() => console.log("end parallel")) + .Start(); + + // Promise + yield this.loadItemAsync("settings.json"); + } + } + + *Coroutine2(num: number, repeat: number) { + for (let i = 0; i < repeat; i++) { + //yield CoroutineV2.WaitTime(2); + yield 0; + console.log(`C2: ${num}`); + // yield CoroutineV2.WaitTime(1); + } + } + + actionCallback() { + console.log("action callback 2"); + } + + loadItemAsync(id: string): Promise<{ id: string }> { + return new Promise((resolve) => { + console.log('loading item start:', id); + setTimeout(() => { + resolve({ id: id }); + console.log('loading item done:', id); + }, 3000); + }); + } +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts.meta new file mode 100644 index 0000000..1c2b129 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "dfd32c11-76f6-4e38-9272-1d7966d1ef3c", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts new file mode 100644 index 0000000..6ad86af --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts @@ -0,0 +1,75 @@ +import { IEnumeratorV2, IEnumeratorV2Started } from "./IEnumeratorV2"; +import { BaseEnumerator } from "./Core/BaseEnumerator"; +import { SingleEnumerator } from "./Core/SingleEnumerator"; +import { ParallelEnumerator } from "./Core/ParallelEnumerator"; +import { WaitTimeEnumerator } from "./Core/WaitTimeEnumerator"; +import { ActionEnumerator } from "./Core/ActionEnumerator"; +import { CoroutineExecutor } from "./Core/CoroutineExecutor"; + +export module CoroutineV2 { + /** + * 啟動一般協程 + */ + export function StartCoroutine(iterator: Iterator, target?: any): IEnumeratorV2Started { + return Single(iterator).Start(target); + } + + /** + * 依據IEnumeratorV2.Start(target)綁定的目標, 來停止協程 + * @param target + */ + export function StopCoroutinesBy(target: any) { + CoroutineExecutor.instance.StopCoroutineBy(target); + } + + /** + * 單一協程 + */ + export function Single(iterator: Iterator): IEnumeratorV2 { + if (iterator instanceof BaseEnumerator) { + return iterator; + } else { + return new SingleEnumerator(iterator); + } + } + + /** + * 平行協程 + */ + export function Parallel(...iterators: Iterator[]): IEnumeratorV2 { + return new ParallelEnumerator(iterators); + } + + /** + * 序列協程 + */ + export function Serial(...iterators: Iterator[]): IEnumeratorV2 { + let [iterator, ...others] = iterators; + if (iterator instanceof BaseEnumerator) { + return iterator.ThenSerial(...others); + } else { + return new SingleEnumerator(iterator).ThenSerial(...others); + } + } + + /** + * 執行方法協程 + * @param action 方法 + * @param delaySeconds 延遲秒數 + */ + export function Action(action: Function, delaySeconds?: number): IEnumeratorV2 { + if (delaySeconds > 0) { + return new WaitTimeEnumerator(delaySeconds).Then(new ActionEnumerator(action)); + } else { + return new ActionEnumerator(action); + } + } + + /** + * 等待時間協程 + * @param seconds 秒數 + */ + export function WaitTime(seconds: number): IEnumeratorV2 { + return new WaitTimeEnumerator(seconds); + } +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts.meta new file mode 100644 index 0000000..6ac7bb1 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "fc38e505-bd37-44c3-9e0a-fd463bb88c51", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts b/src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts new file mode 100644 index 0000000..4dcacba --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts @@ -0,0 +1,16 @@ +export interface IEnumeratorV2 extends Iterator { + Start(target?: any): IEnumeratorV2Started; + Then(iterator: Iterator): IEnumeratorV2; + ThenSerial(...iterators: Iterator[]): IEnumeratorV2; + ThenParallel(...iterators: Iterator[]): IEnumeratorV2; + ThenAction(action: Function, delaySeconds?: number): IEnumeratorV2; + ThenWaitTime(seconds: number): IEnumeratorV2; +} + +export interface IEnumeratorV2Started { + readonly Current: any; + + Pause(): void; + Resume(): void; + Stop(): void; +} diff --git a/src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts.meta b/src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts.meta new file mode 100644 index 0000000..a4feac9 --- /dev/null +++ b/src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "df3ab07d-3d2b-4552-b454-29b95223ea85", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2.meta b/src/script/Engine/CatanEngine/NetManagerV2.meta new file mode 100644 index 0000000..cb48b8a --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "6f870efd-e869-4415-9cf2-138ab667cd5d", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Core.meta b/src/script/Engine/CatanEngine/NetManagerV2/Core.meta new file mode 100644 index 0000000..a05aca1 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Core.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "5e6c027f-ce4b-47fa-968c-f3bb6059ad81", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Core/INetConnector.ts b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetConnector.ts new file mode 100644 index 0000000..8017183 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetConnector.ts @@ -0,0 +1,13 @@ +import { Action } from "../../CSharp/System/Action"; +import { INetRequest } from "./INetRequest"; +import { INetResponse } from "./INetResponse"; + +export interface INetConnector { + readonly OnDataReceived: Action>; + readonly OnDisconnected: Action; + readonly IsConnected: boolean; + + SendAsync(req: INetRequest): Iterator; + Send(req: INetRequest); + Logout(); +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Core/INetConnector.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetConnector.ts.meta new file mode 100644 index 0000000..75c86ab --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetConnector.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "f97991b5-0da6-4220-ab29-13c8f8f7e405", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Core/INetRequest.ts b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetRequest.ts new file mode 100644 index 0000000..afe77ed --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetRequest.ts @@ -0,0 +1,12 @@ +import { INetResponse } from "./INetResponse"; + +export interface INetRequest { + readonly Method: string; + readonly MethodBack: string; + + Data: TRequest; + Result: INetResponse; + + SendAsync(): Promise>; + Send(); +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Core/INetRequest.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetRequest.ts.meta new file mode 100644 index 0000000..dc644ba --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetRequest.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "339fcf27-bdb9-4b8f-ae18-dd54c9500145", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Core/INetResponse.ts b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetResponse.ts new file mode 100644 index 0000000..ccc08e2 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetResponse.ts @@ -0,0 +1,6 @@ +export interface INetResponse { + readonly Method: string; + readonly Status: number; + readonly Data: TResponse; + readonly IsValid: boolean; +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Core/INetResponse.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetResponse.ts.meta new file mode 100644 index 0000000..1861d9d --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Core/INetResponse.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "c4cb0cd4-b98c-4f8e-b1e6-ac3b51281b28", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Examples.meta b/src/script/Engine/CatanEngine/NetManagerV2/Examples.meta new file mode 100644 index 0000000..ddcf31a --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Examples.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "94e55972-723c-4dab-9ebc-870bd5043fca", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Examples/NetTester.ts b/src/script/Engine/CatanEngine/NetManagerV2/Examples/NetTester.ts new file mode 100644 index 0000000..34cfa74 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Examples/NetTester.ts @@ -0,0 +1,69 @@ +import { CoroutineV2 } from "../../CoroutineV2/CoroutineV2"; +import { INetResponse } from "../Core/INetResponse"; +import { NetConnector } from "../NetConnector"; +import { NetManager } from "../NetManager"; +import { Slot1_SpinRequestExample } from "./Slot1_SpinRequestExample"; + +const { ccclass, property } = console._decorator; + +@ccclass +export default class NetTester extends console.Component { + + onConnectClicked() { + CoroutineV2.StartCoroutine(this.ConnectAsync()); + } + + *ConnectAsync() { + if (!NetManager.HasInit) { + let conn = new NetConnector("192.168.7.165", 9005); + conn.OnDataReceived.AddCallback(this.OnNetDataReceived, this); + conn.OnDisconnected.AddCallback(this.OnNetDisconnected, this); + conn.OnLoadUIMask.AddCallback(this.OnLoadUIMask, this); + + NetManager.Initialize(conn); + } + + console.log("連線中..."); + yield NetManager.ConnectAsync(); // 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect() + console.log(`連線狀態: ${NetManager.IsConnected}`); + } + + onDisconnectClicked() { + console.log("中斷連線中..."); + NetManager.Disconnect(); // 中斷連線 + } + + onSendMessageClicked1() { + console.log("發送訊息(不使用協程)"); + let req = new Slot1_SpinRequestExample(401); + req.Send(); + // CasinoNetManager.Send(req); + } + + onSendMessageClicked2() { + CoroutineV2.StartCoroutine(this.SendAsync()); + } + + *SendAsync() { + console.log("發送訊息中(使用協程)..."); + let req = new Slot1_SpinRequestExample(399); + yield req.SendAsync(); + // yield CasinoNetManager.SendAsync(req); + + let resp = req.Result; + console.log(`發送協程完畢, Server回應: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); + // console.log(`使用介面資料: ${resp.Data.slot}`); + } + + private OnNetDisconnected() { + console.log("[事件] 收到連線中斷事件"); + } + + private OnNetDataReceived(resp: INetResponse) { + console.log(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); + } + + private OnLoadUIMask(value: boolean) { + console.log(`[事件] LoadUIMask: ${value}`); + } +} diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Examples/NetTester.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/Examples/NetTester.ts.meta new file mode 100644 index 0000000..9cfea89 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Examples/NetTester.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "0cb7df7a-d0e7-4ce1-832e-4583cf3385e5", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Examples/Slot1_SpinRequestExample.ts b/src/script/Engine/CatanEngine/NetManagerV2/Examples/Slot1_SpinRequestExample.ts new file mode 100644 index 0000000..0bd72c9 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Examples/Slot1_SpinRequestExample.ts @@ -0,0 +1,37 @@ +import { NetRequest } from "../NetRequest"; + +// 送給server的結構 +interface Request { + pay: number; +} + +// server回應的結構 +interface Response { + pay: [[number, number]]; + /**拉霸結果 */ + slot: number[]; + get: any[]; +} + +// class Account_CreateRequest extends CasinoRequest { // 也可以是基本類或any, 但不建議用any, 使用介面ts才會有提示 +export class Slot1_SpinRequestExample extends NetRequest { + get Method(): string { + return "slot1.spin"; + } + + // MethodBack預設回傳Method, 不一樣才需要覆寫 + // get MethodBack(): string { + // return "slot1.freespin"; + // } + + constructor(totalBet: number) { + super(); + + // 原本的SingleValue拿掉, 統一使用Data來存送出結構 + + // this.Data = 2; + this.Data = { + pay: totalBet, + }; + } +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/Examples/Slot1_SpinRequestExample.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/Examples/Slot1_SpinRequestExample.ts.meta new file mode 100644 index 0000000..8a7d3bc --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/Examples/Slot1_SpinRequestExample.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "1af9e6af-3dc3-4d02-8b24-481adc07932a", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts b/src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts new file mode 100644 index 0000000..3fe2b99 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts @@ -0,0 +1,4 @@ +export default class NetConfig { + /**是否顯示RPC接送JSON的LOG */ + public static ShowServerLog: boolean = true; +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts.meta new file mode 100644 index 0000000..14afee9 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "c7f5f6a9-94fd-4f5f-9f0a-545cd14edca9", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts b/src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts new file mode 100644 index 0000000..77ba94a --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts @@ -0,0 +1,263 @@ +import { Tools } from "../../../Tools"; +import { BaseEnumerator } from "../CoroutineV2/Core/BaseEnumerator"; +import { Action } from "../CSharp/System/Action"; +import { Encoding } from "../CSharp/System/Text/Encoding"; +import { INetRequest } from "./Core/INetRequest"; +import { INetResponse } from "./Core/INetResponse"; +import NetConfig from "./NetConfig"; +import { NetManager } from "./NetManager"; + +export class NetConnector { + readonly OnDataReceived: Action> = new Action>(); + readonly OnDisconnected: Action = new Action(); + readonly OnLoadUIMask: Action = new Action(); + + get IsConnected() { + return this._ws && this._ws.readyState === WebSocket.OPEN; + } + + private _host: string; + private _ws: WebSocket = null!; + private _waitings: WsRequestEnumerator[] = []; + + constructor(host: string, port: number, ip: string) { + let checkHttp: string = ""; + let index: number = host.indexOf("https://"); + if (index != -1) { + checkHttp = "https"; + host = host.replace("https://", ""); + } else { + checkHttp = window.location.href.substring(0, 5); + host = host.replace("http://", ""); + } + if (true) { + console.log("[事件]checkHttp=", checkHttp, host, port); + } + if (checkHttp != "https") { + this._host = `ws://${host}:${port}/?ip=${ip}`; + } + else { + this._host = `wss://${host}:${port}/?ip=${ip}`; + } + } + + async ConnectAsync() { + if (this._ws) { + throw new Error("請先執行CasinoNetManager.Disconnect()中斷連線"); + } + this._ws = new WebSocket(this._host); + + this._ws.binaryType = 'arraybuffer'; + this._ws.onopen = this.OnWebSocketOpen.bind(this); + this._ws.onmessage = this.OnWebSocketMessage.bind(this); + this._ws.onerror = this.OnWebSocketError.bind(this); + this._ws.onclose = this.OnWebSocketClose.bind(this); + + while (!NetManager.IsConnected) { + await Tools.Sleep(1); + } + return new WsConnectEnumerator(this._ws); + } + + async Send(req: INetRequest) { + if (!this.IsConnected) return; + + let json = [req.Method]; + if (req.Data != null && req.Data != undefined && req.Data) { + json[1] = req.Data; + } + + if (true && NetConfig.ShowServerLog) { + if (req.Data != null && req.Data != undefined && req.Data) { + console.log(`[RPC] 傳送server資料: ${req.Method}(${JSON.stringify(req.Data)})`); + } else { + console.log(`[RPC] 傳送server資料: ${req.Method}()`); + } + } + + let str = JSON.stringify(json); + if (str.length > 65535) { + throw new Error('要傳的資料太大囉'); + } + + let strary = Encoding.UTF8.GetBytes(str); + let buffer = new Uint8Array(4 + strary.byteLength); + let u16ary = new Uint16Array(buffer.buffer, 0, 3); + u16ary[0] = strary.byteLength; + buffer[3] = 0x01; + buffer.set(strary, 4); + + await this._ws.send(buffer); + } + + async SendAsync(req: INetRequest, mask: boolean) { + let iterator = new WsRequestEnumerator(req); + if (!this.IsConnected) { + iterator.SetResponse(ErrorResponse); + } else { + this._waitings.push(iterator); + if (mask) { + this.OnLoadUIMask.DispatchCallback(true); + } + this.Send(req); + while (!iterator.Done) { + await Tools.Sleep(1); + } + + } + return iterator; + }; + + Disconnect() { + this.WebSocketEnded(); + } + + private WebSocketEnded() { + if (!this._ws) return; + + this._ws.close(); + this._ws.onopen = null; + this._ws.onmessage = null; + this._ws.onclose = () => { }; + this._ws = null!; + + this.CleanWaitings(); + this.OnDisconnected.DispatchCallback(); + } + + private CleanWaitings() { + for (let w of this._waitings) { + w.SetResponse(ErrorResponse); + this.OnLoadUIMask.DispatchCallback(false); + } + this._waitings.length = 0; + } + + private OnWebSocketOpen(e: Event) { + if (true) { + console.log(`[RPC] ${this._host} Connected.`); + } + } + + private OnWebSocketMessage(e: MessageEvent) { + if (e.data instanceof ArrayBuffer) { + this.ParseRpcMessage(e.data); + } else if (e.data instanceof Blob) { + let reader = new FileReader(); + reader.onload = (e) => { this.ParseRpcMessage(reader.result); reader.onload = null; } + reader.readAsArrayBuffer(e.data); + } else { + throw new Error(`未知的OnWebSocketMessage(e.data)類型: ${e.data}`); + } + } + + private ParseRpcMessage(buffer: ArrayBuffer) { + let startIndex = 0, byteLength = buffer.byteLength; + while (startIndex + 4 < byteLength) { + let strlen = new DataView(buffer, startIndex, 3).getUint16(0, true); + let str = Encoding.UTF8.GetString(new Uint8Array(buffer, startIndex + 4, strlen)); + startIndex += strlen + 4; + + try { + let json = JSON.parse(str); + let method = json[0]; + let status = json[1][0]; + let data = json[1][1]; + + let resp = >{ + Method: method, + Status: status, + Data: data, + IsValid: method && status === 0 + }; + + if (true && NetConfig.ShowServerLog) { + if (data) { + console.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}(${JSON.stringify(resp.Data)})`); + } else { + console.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}()`); + } + } + + let dispatch = true; + for (let i = 0, len = this._waitings.length; i < len; i++) { + let w = this._waitings[i]; + if (w.MethodBack === resp.Method) { + dispatch = false; + this._waitings.splice(i, 1); + w.SetResponse(resp); + this.OnLoadUIMask.DispatchCallback(false); + break; + } + } + + if (dispatch) { + this.OnDataReceived.DispatchCallback(resp); + } + } + catch + { + throw new Error(`[RPC] 無法解析Server回應: ${str}`); + } + } + } + + private OnWebSocketError(ev: Event) { + throw new Error(`[RPC] 無法解析Server回應: ${ev}`); + } + + private OnWebSocketClose(e: CloseEvent) { + this.WebSocketEnded(); + } +} + +const ErrorResponse: INetResponse = { + Status: -1, + Method: "", + Data: {}, + IsValid: false, +}; + +class WsConnectEnumerator extends BaseEnumerator { + private _ws: WebSocket; + + constructor(ws: WebSocket) { + super(); + this._ws = ws; + } + + next(value?: any): IteratorResult { + return { + done: this._ws.readyState === WebSocket.OPEN || this._ws.readyState === WebSocket.CLOSED, + value: undefined + }; + } +} + +class WsRequestEnumerator extends BaseEnumerator { + readonly MethodBack: string; + + private _req: INetRequest; + private _done: boolean = false; + + public get Done(): boolean { return this._done; } + + constructor(req: INetRequest) { + super(); + + this._req = req; + this.MethodBack = req.MethodBack; + } + + SetResponse(resp: INetResponse) { + this._req.Result = resp; + this._done = true; + } + + next(value?: any): IteratorResult { + return { + done: this._done, + value: undefined + }; + } +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts.meta new file mode 100644 index 0000000..99a8b42 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "221e1688-cc40-450d-9248-464978540a85", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts b/src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts new file mode 100644 index 0000000..d84bcf0 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts @@ -0,0 +1,49 @@ +import { INetRequest } from "./Core/INetRequest"; +import { NetConnector } from "./NetConnector"; + +export class NetManager { + static get IsConnected() { return this._connector && this._connector.IsConnected; } + static get HasInit() { return this._connector != null; } + + private static _connector: NetConnector; + + static Initialize(connector: NetConnector) { + this._connector = connector; + } + + static async ConnectAsync() { + this.CheckConnector(); + return await this._connector.ConnectAsync(); + } + + /** + * 斷線 + */ + static Disconnect() { + this.CheckConnector(); + this._connector.Disconnect(); + } + + /** + * 傳送資料給Server, 不等待回應 + * @param req + */ + static Send(req: INetRequest) { + this.CheckConnector(); + this._connector.Send(req); + } + + /** + * 傳送資料給Server, 並等待回應 + * @param req + */ + static async SendAsync(req: INetRequest, mask: boolean) { + this.CheckConnector(); + return await this._connector.SendAsync(req, mask); + } + + private static CheckConnector() { + if (!this._connector) throw new Error("請先呼叫CasinoNetManager.Initialize()初始化connector"); + } + +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts.meta new file mode 100644 index 0000000..3b9b3ba --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "7c3e375d-3672-42e7-8a45-dd5ecf9d5fe8", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts b/src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts new file mode 100644 index 0000000..b5c6c04 --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts @@ -0,0 +1,21 @@ +import { INetRequest } from "./Core/INetRequest"; +import { NetManager } from "./NetManager"; + +export abstract class NetRequest implements INetRequest { + abstract get Method(): string; + + get MethodBack(): string { + return this.Method; + } + + Data: TResquest; + Result: import("./Core/INetResponse").INetResponse; + + async SendAsync(mask: boolean = false): Promise> { + return await NetManager.SendAsync(this, mask); + } + + Send() { + NetManager.Send(this); + } +} diff --git a/src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts.meta b/src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts.meta new file mode 100644 index 0000000..13db2ab --- /dev/null +++ b/src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "36534597-4273-48e8-bbeb-8dde4857d26f", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NoSleep.ts b/src/script/Engine/CatanEngine/NoSleep.ts new file mode 100644 index 0000000..6cfe540 --- /dev/null +++ b/src/script/Engine/CatanEngine/NoSleep.ts @@ -0,0 +1,81 @@ +export class NoSleep { + static oldIOS: boolean = typeof navigator !== 'undefined' && parseFloat(('' + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0, ''])[1]).replace('undefined', '3_2').replace('_', '.').replace('_', '')) < 10 && !window["MSStream"]; + static webm: string = 'data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA='; + static mp4: string = 'data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQADQGgcIQADQGgcAAAACQGeYUQn/wALKCEAA0BoHAAAAAkBnmNEJ/8ACykhAANAaBwhAANAaBwAAAANQZpoNExDP/6plgAMuSEAA0BoHAAAAAtBnoZFESwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBnqVEJ/8ACykhAANAaBwAAAAJAZ6nRCf/AAsoIQADQGgcIQADQGgcAAAADUGarDRMQz/+qZYADLghAANAaBwAAAALQZ7KRRUsK/8ACPkhAANAaBwAAAAJAZ7pRCf/AAsoIQADQGgcIQADQGgcAAAACQGe60Qn/wALKCEAA0BoHAAAAA1BmvA0TEM//qmWAAy5IQADQGgcIQADQGgcAAAAC0GfDkUVLCv/AAj5IQADQGgcAAAACQGfLUQn/wALKSEAA0BoHCEAA0BoHAAAAAkBny9EJ/8ACyghAANAaBwAAAANQZs0NExDP/6plgAMuCEAA0BoHAAAAAtBn1JFFSwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBn3FEJ/8ACyghAANAaBwAAAAJAZ9zRCf/AAsoIQADQGgcIQADQGgcAAAADUGbeDRMQz/+qZYADLkhAANAaBwAAAALQZ+WRRUsK/8ACPghAANAaBwhAANAaBwAAAAJAZ+1RCf/AAspIQADQGgcAAAACQGft0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bm7w0TEM//qmWAAy4IQADQGgcAAAAC0Gf2kUVLCv/AAj5IQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHAAAAAkBn/tEJ/8ACykhAANAaBwAAAANQZvgNExDP/6plgAMuSEAA0BoHCEAA0BoHAAAAAtBnh5FFSwr/wAI+CEAA0BoHAAAAAkBnj1EJ/8ACyghAANAaBwhAANAaBwAAAAJAZ4/RCf/AAspIQADQGgcAAAADUGaJDRMQz/+qZYADLghAANAaBwAAAALQZ5CRRUsK/8ACPkhAANAaBwhAANAaBwAAAAJAZ5hRCf/AAsoIQADQGgcAAAACQGeY0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bmmg0TEM//qmWAAy5IQADQGgcAAAAC0GehkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGepUQn/wALKSEAA0BoHAAAAAkBnqdEJ/8ACyghAANAaBwAAAANQZqsNExDP/6plgAMuCEAA0BoHCEAA0BoHAAAAAtBnspFFSwr/wAI+SEAA0BoHAAAAAkBnulEJ/8ACyghAANAaBwhAANAaBwAAAAJAZ7rRCf/AAsoIQADQGgcAAAADUGa8DRMQz/+qZYADLkhAANAaBwhAANAaBwAAAALQZ8ORRUsK/8ACPkhAANAaBwAAAAJAZ8tRCf/AAspIQADQGgcIQADQGgcAAAACQGfL0Qn/wALKCEAA0BoHAAAAA1BmzQ0TEM//qmWAAy4IQADQGgcAAAAC0GfUkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGfcUQn/wALKCEAA0BoHAAAAAkBn3NEJ/8ACyghAANAaBwhAANAaBwAAAANQZt4NExC//6plgAMuSEAA0BoHAAAAAtBn5ZFFSwr/wAI+CEAA0BoHCEAA0BoHAAAAAkBn7VEJ/8ACykhAANAaBwAAAAJAZ+3RCf/AAspIQADQGgcAAAADUGbuzRMQn/+nhAAYsAhAANAaBwhAANAaBwAAAAJQZ/aQhP/AAspIQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHAAACiFtb292AAAAbG12aGQAAAAA1YCCX9WAgl8AAAPoAAAH/AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAGGlvZHMAAAAAEICAgAcAT////v7/AAAF+XRyYWsAAABcdGtoZAAAAAPVgIJf1YCCXwAAAAEAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAygAAAMoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAABdwAAEAAAAABXFtZGlhAAAAIG1kaGQAAAAA1YCCX9WAgl8AAV+QAAK/IFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAUcbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAE3HN0YmwAAACYc3RzZAAAAAAAAAABAAAAiGF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAygDKAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAyYXZjQwFNQCj/4QAbZ01AKOyho3ySTUBAQFAAAAMAEAAr8gDxgxlgAQAEaO+G8gAAABhzdHRzAAAAAAAAAAEAAAA8AAALuAAAABRzdHNzAAAAAAAAAAEAAAABAAAB8GN0dHMAAAAAAAAAPAAAAAEAABdwAAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAAC7gAAAAAQAAF3AAAAABAAAAAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAEEc3RzegAAAAAAAAAAAAAAPAAAAzQAAAAQAAAADQAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAANAAAADQAAAQBzdGNvAAAAAAAAADwAAAAwAAADZAAAA3QAAAONAAADoAAAA7kAAAPQAAAD6wAAA/4AAAQXAAAELgAABEMAAARcAAAEbwAABIwAAAShAAAEugAABM0AAATkAAAE/wAABRIAAAUrAAAFQgAABV0AAAVwAAAFiQAABaAAAAW1AAAFzgAABeEAAAX+AAAGEwAABiwAAAY/AAAGVgAABnEAAAaEAAAGnQAABrQAAAbPAAAG4gAABvUAAAcSAAAHJwAAB0AAAAdTAAAHcAAAB4UAAAeeAAAHsQAAB8gAAAfjAAAH9gAACA8AAAgmAAAIQQAACFQAAAhnAAAIhAAACJcAAAMsdHJhawAAAFx0a2hkAAAAA9WAgl/VgIJfAAAAAgAAAAAAAAf8AAAAAAAAAAAAAAABAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAACsm1kaWEAAAAgbWRoZAAAAADVgIJf1YCCXwAArEQAAWAAVcQAAAAAACdoZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU3RlcmVvAAAAAmNtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAidzdGJsAAAAZ3N0c2QAAAAAAAAAAQAAAFdtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAArEQAAAAAADNlc2RzAAAAAAOAgIAiAAIABICAgBRAFQAAAAADDUAAAAAABYCAgAISEAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAABYAAAEAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAAGAAAAWAAAAXBzdGNvAAAAAAAAAFgAAAOBAAADhwAAA5oAAAOtAAADswAAA8oAAAPfAAAD5QAAA/gAAAQLAAAEEQAABCgAAAQ9AAAEUAAABFYAAARpAAAEgAAABIYAAASbAAAErgAABLQAAATHAAAE3gAABPMAAAT5AAAFDAAABR8AAAUlAAAFPAAABVEAAAVXAAAFagAABX0AAAWDAAAFmgAABa8AAAXCAAAFyAAABdsAAAXyAAAF+AAABg0AAAYgAAAGJgAABjkAAAZQAAAGZQAABmsAAAZ+AAAGkQAABpcAAAauAAAGwwAABskAAAbcAAAG7wAABwYAAAcMAAAHIQAABzQAAAc6AAAHTQAAB2QAAAdqAAAHfwAAB5IAAAeYAAAHqwAAB8IAAAfXAAAH3QAAB/AAAAgDAAAICQAACCAAAAg1AAAIOwAACE4AAAhhAAAIeAAACH4AAAiRAAAIpAAACKoAAAiwAAAItgAACLwAAAjCAAAAFnVkdGEAAAAObmFtZVN0ZXJlbwAAAHB1ZHRhAAAAaG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAO2lsc3QAAAAzqXRvbwAAACtkYXRhAAAAAQAAAABIYW5kQnJha2UgMC4xMC4yIDIwMTUwNjExMDA='; + + static hasInit: boolean = false; + static noSleepTimer: number; + static noSleepVideo: HTMLVideoElement; + static isStart: boolean; + + public static init() { + if (this.hasInit) return; + + if (!this.oldIOS) { + let noSleepVideo = document.createElement('video'); + + noSleepVideo.setAttribute('muted', ''); + noSleepVideo.setAttribute('title', 'Intro'); + noSleepVideo.setAttribute('playsinline', ''); + + this.addSourceToVideo(noSleepVideo, 'webm', this.webm); + this.addSourceToVideo(noSleepVideo, 'mp4', this.mp4); + + noSleepVideo.addEventListener('loadedmetadata', function () { + if (noSleepVideo.duration <= 1) { + noSleepVideo.setAttribute('loop', ''); + } else { + noSleepVideo.addEventListener('timeupdate', function () { + if (noSleepVideo.currentTime > 0.5) { + noSleepVideo.currentTime = Math.random(); + } + }); + } + }); + + document.body.appendChild(noSleepVideo); + this.noSleepVideo = noSleepVideo; + } + + this.hasInit = true; + this.isStart = false; + } + + public static start() { + if (!this.isStart) { + console.log("nosleep start"); + if (this.oldIOS) { + this.stop(); + this.noSleepTimer = window.setInterval(() => { + if (!document.hidden) { + window.location.href = window.location.href.split('#')[0]; + window.setTimeout(window.stop, 0); + } + }, 15000); + } else { + this.noSleepVideo.play(); + } + this.isStart = true; + } + } + + public static stop() { + if (this.oldIOS) { + if (this.noSleepTimer) { + window.clearInterval(this.noSleepTimer); + this.noSleepTimer = 0; + } + } else { + this.noSleepVideo.pause(); + } + this.isStart = false; + } + + static addSourceToVideo(element: HTMLVideoElement, type: string, dataURI: string) { + let source = document.createElement('source'); + source.src = dataURI; + source.type = 'video/' + type; + element.appendChild(source); + } + +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/NoSleep.ts.meta b/src/script/Engine/CatanEngine/NoSleep.ts.meta new file mode 100644 index 0000000..836b5c4 --- /dev/null +++ b/src/script/Engine/CatanEngine/NoSleep.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "90f2152c-2c37-4c7c-b3a3-04c8aee53c34", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/TableV3.meta b/src/script/Engine/CatanEngine/TableV3.meta new file mode 100644 index 0000000..dcae6d1 --- /dev/null +++ b/src/script/Engine/CatanEngine/TableV3.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "8e05805d-5ab8-4526-8463-f4c837e23534", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/CatanEngine/公司自架接功能.txt b/src/script/Engine/CatanEngine/公司自架接功能.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/script/Engine/CatanEngine/公司自架接功能.txt.meta b/src/script/Engine/CatanEngine/公司自架接功能.txt.meta new file mode 100644 index 0000000..689bc66 --- /dev/null +++ b/src/script/Engine/CatanEngine/公司自架接功能.txt.meta @@ -0,0 +1,5 @@ +{ + "ver": "2.0.0", + "uuid": "6ab253ff-8c5d-419f-9f8b-5cf0ef661a28", + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Component.meta b/src/script/Engine/Component.meta new file mode 100644 index 0000000..5b7af33 --- /dev/null +++ b/src/script/Engine/Component.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "c87ad2c2-0bf9-4822-84db-00b939f614ee", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Data.meta b/src/script/Engine/Data.meta new file mode 100644 index 0000000..00c18b4 --- /dev/null +++ b/src/script/Engine/Data.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "89d65072-29d8-4f58-a9d7-5750406209e6", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/HotUpdate.meta b/src/script/Engine/HotUpdate.meta new file mode 100644 index 0000000..fcdb51f --- /dev/null +++ b/src/script/Engine/HotUpdate.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "10da37ee-322f-492b-b19b-ed0cd210e884", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils.meta b/src/script/Engine/Utils.meta new file mode 100644 index 0000000..7b1bd0e --- /dev/null +++ b/src/script/Engine/Utils.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "1207e3f9-4c55-4435-a3be-3d04c6806a1f", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Act.meta b/src/script/Engine/Utils/Act.meta new file mode 100644 index 0000000..ca8d9f1 --- /dev/null +++ b/src/script/Engine/Utils/Act.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "b43bf5ea-67c5-4fc8-9893-1f406a52508f", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Act/Shake.ts b/src/script/Engine/Utils/Act/Shake.ts new file mode 100644 index 0000000..ed39dce --- /dev/null +++ b/src/script/Engine/Utils/Act/Shake.ts @@ -0,0 +1,55 @@ +const { ccclass } = console._decorator; + +@ccclass +export default class Shake extends console.ActionInterval { + private _init: boolean = false; + private _initial_x: number = 0; + private _initial_y: number = 0; + private _strength_x: number = 0; + private _strength_y: number = 0; + + /** + * 建立抖動動畫 + * @param {number} duration 動畫持續時長 + * @param {number} strength_x 抖動幅度: x方向 + * @param {number} strength_y 抖動幅度: y方向 + * @returns {Shake} + */ + public static create(duration: number, strength_x: number, strength_y: number): Shake { + let act: Shake = new Shake(); + act.initWithDuration(duration, strength_x, strength_y); + return act; + } + + public initWithDuration(duration: number, strength_x: number, strength_y: number): boolean { + console.ActionInterval.prototype['initWithDuration'].apply(this, arguments); + this._strength_x = strength_x; + this._strength_y = strength_y; + return true; + } + + public fgRangeRand(min: number, max: number): number { + let rnd: number = Math.random(); + return rnd * (max - min) + min; + } + + public update(time: number): void { + let randx = this.fgRangeRand(-this._strength_x, this._strength_x); + let randy = this.fgRangeRand(-this._strength_y, this._strength_y); + this.getTarget().setPosition(randx + this._initial_x, randy + this._initial_y); + } + + public startWithTarget(target: console.Node): void { + console.ActionInterval.prototype['startWithTarget'].apply(this, arguments); + if (!this._init) { + this._init = true; + this._initial_x = target.x; + this._initial_y = target.y; + } + } + + public stop(): void { + this.getTarget().setPosition(new console.Vec2(this._initial_x, this._initial_y)); + console.ActionInterval.prototype['stop'].apply(this); + } +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Act/Shake.ts.meta b/src/script/Engine/Utils/Act/Shake.ts.meta new file mode 100644 index 0000000..e6b212e --- /dev/null +++ b/src/script/Engine/Utils/Act/Shake.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "c5872cc0-91a4-49cb-a055-e037accd801d", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Audio.meta b/src/script/Engine/Utils/Audio.meta new file mode 100644 index 0000000..6f27799 --- /dev/null +++ b/src/script/Engine/Utils/Audio.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "d042d487-d962-4d90-920e-70ab9b8b383c", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Audio/CSAudio.ts b/src/script/Engine/Utils/Audio/CSAudio.ts new file mode 100644 index 0000000..f88c871 --- /dev/null +++ b/src/script/Engine/Utils/Audio/CSAudio.ts @@ -0,0 +1,184 @@ +import LocalStorageData from "../../Data/LocalStorageData"; + +export default class CSAudio { + private static _instance: CSAudio = null; + public static get Instance(): CSAudio { return this._instance; } + private _idToClip: Map = new Map(); + private _idToPath: Map = new Map(); + private _idToAudioId: Map = new Map(); + private _currentMusic: number = -1; + /**判斷音效播放太過頻繁不疊加 */ + private _lastPlaySoundTime: Map = new Map(); + private readonly _canPlaySoundCutTime: number = 10; + + constructor() { + CSAudio._instance = this; + if (LocalStorageData.Instance.MusicType) { + this.SetMusicVolume(+LocalStorageData.Instance.MusicType); + } else { + this.SetMusicVolume(0.3); + } + if (LocalStorageData.Instance.SoundType) { + this.SetSoundVolume(+LocalStorageData.Instance.SoundType); + } else { + this.SetSoundVolume(0.3); + } + } + + public AddClipsInfo(clips: Map, pathes: Map): void { + this._idToClip = clips; + this._idToPath = pathes; + } + + /** + * 設定AudioID + * @param id + * @param audioId + */ + private _setAudioId(id: number, audioId: number): void { + this._idToAudioId.set(id, audioId); + } + + /** + * 取得AudioID + * @param id + */ + private _getAudioId(id: number): number { + if (this._idToAudioId.has(id)) { + return this._idToAudioId.get(id); + } else { + return -1; + } + } + + /** + * 打開音效音量 + */ + public OpenSound(): void { + this.SetSoundVolume(0.3); + } + /** + * 關閉音效音量 + */ + public CloseSound(): void { + this.SetSoundVolume(0.0); + } + + /** + * 設定音效音量 + * @param volume + */ + public SetSoundVolume(volume: number): void { + LocalStorageData.Instance.SoundType = volume.toString(); + console.audioEngine.setEffectsVolume(volume); + } + + /** + * 播放音效 + * @param id + * @param loop + */ + public PlaySound(id: number, loop: boolean = false): void { + // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 + if (console.audioEngine.getEffectsVolume() <= 0) { + return; + } + if (this._idToClip.has(id)) { + let path: string = this._idToPath.get(id); + let timenum: number = new Date().getTime(); + if (!this._lastPlaySoundTime.has(path)) { + this._lastPlaySoundTime.set(path, timenum); + let audioId: number = console.audioEngine.playEffect(this._idToClip.get(id), loop); + this._setAudioId(id, audioId); + } else { + let lastTime: number = this._lastPlaySoundTime.get(path); + if (timenum - lastTime > this._canPlaySoundCutTime) { + this._lastPlaySoundTime.set(path, timenum); + let audioId: number = console.audioEngine.playEffect(this._idToClip.get(id), loop); + this._setAudioId(id, audioId); + } + } + } else { + console.error("未知的Sound Id: ", id); + } + } + + /** + * 停止音效 + * @param id + */ + public StopSound(id: number): void { + let audioId = this._getAudioId(id); + if (audioId >= 0) { + console.audioEngine.stopEffect(audioId); + } + } + + /** + * 打開音樂音量 + */ + public OpenMusic(): void { + this.SetMusicVolume(0.3); + } + /** + * 關閉音樂音量 + */ + public CloseMusic(): void { + this.SetMusicVolume(0.0); + } + + /** + * 設定音樂音量 + * @param volume + */ + public SetMusicVolume(volume: number): void { + console.audioEngine.setMusicVolume(volume); + LocalStorageData.Instance.MusicType = volume.toString(); + // 靜音後有一禎仍然會撥放的問題:背景音樂要回復 + if (this._currentMusic != -1 && volume > 0 && !console.audioEngine.isMusicPlaying()) { + this._ccMusicPlayId = console.audioEngine.playMusic(this._idToClip.get(this._currentMusic), true); + } + } + + /** + * 撥放音樂 + * @param id + * @param loop + */ + public PlayMusic(id: number, loop: boolean = true): void { + if (this._currentMusic != id) { + if (this._idToClip.has(id)) { + // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 + if (console.audioEngine.getMusicVolume() > 0) { + this._ccMusicPlayId = console.audioEngine.playMusic(this._idToClip.get(id), loop); + } + this._currentMusic = id; + } + else { + console.error("未知的Music Id: ", id); + } + } + } + private _ccMusicPlayId: number = -1; + private _currentMusicTime: number = -1; + public pauseOrResume(isPause?: boolean) { + if (isPause) { + this._currentMusicTime = console.audioEngine.getCurrentTime(this._ccMusicPlayId); + console.audioEngine.pauseAll(); + console.audioEngine.stopMusic(); + } else { + console.audioEngine.resumeAll(); + console.audioEngine.setCurrentTime(this._ccMusicPlayId, this._currentMusicTime); + } + } + + /** + * 停止音樂 + * @param id + */ + public StopMusic(): void { + console.audioEngine.stopMusic(); + this._currentMusic = -1; + } + +} diff --git a/src/script/Engine/Utils/Audio/CSAudio.ts.meta b/src/script/Engine/Utils/Audio/CSAudio.ts.meta new file mode 100644 index 0000000..c788d2c --- /dev/null +++ b/src/script/Engine/Utils/Audio/CSAudio.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "f3ba292a-ecad-4485-ab60-1cd3ee94979a", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Audio/CSCommonAudios.ts b/src/script/Engine/Utils/Audio/CSCommonAudios.ts new file mode 100644 index 0000000..6e7de77 --- /dev/null +++ b/src/script/Engine/Utils/Audio/CSCommonAudios.ts @@ -0,0 +1,167 @@ +import CSAudio from "./CSAudio"; + +export default class CSAppAudios extends CSAudio { + private static _instanceApp: CSAppAudios = null; + public static get InstanceApp(): CSAppAudios { return this._instanceApp; } + private _idToAppClip: Map = new Map(); + private _idToAppPath: Map = new Map(); + private _idToAppAudioId: Map = new Map(); + private _currentAppMusic: number = -1; + /** 判斷音效播放太過頻繁不疊加 */ + private _lastAppPlaySoundTime: Map = new Map(); + private readonly _appCanPlaySoundCutTime: number = 10; + constructor() { + super(); + CSAppAudios._instanceApp = this; + } + + public AddAppClipsInfo(clips: Map, pathes: Map): void { + this._idToAppClip = clips; + this._idToAppPath = pathes; + } + + /** + * 設定AudioID + * @param id + * @param audioId + */ + private _setAppAudioId(id: number, audioId: number): void { + this._idToAppAudioId.set(id, audioId); + } + + /** + * 打開音效音量 + */ + public OpenSound(): void { + super.OpenSound(); + } + /** + * 關閉音效音量 + */ + public CloseSound(): void { + super.CloseSound(); + } + + /** + * 取得AudioID + * @param id + */ + private _getAppAudioId(id: number): number { + if (this._idToAppAudioId.has(id)) { + return this._idToAppAudioId.get(id); + } else { + return -1; + } + } + + /** + * 播放音效 + * @param id + * @param loop + */ + public PlayAppSound(id: number, loop: boolean = false): void { + // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 + if (console.audioEngine.getEffectsVolume() <= 0) { + return; + } + if (this._idToAppClip.has(id)) { + let path: string = this._idToAppPath.get(id); + let timenum: number = new Date().getTime(); + if (!this._lastAppPlaySoundTime.has(path)) { + this._lastAppPlaySoundTime.set(path, timenum); + let audioId: number = console.audioEngine.playEffect(this._idToAppClip.get(id), loop); + this._setAppAudioId(id, audioId); + } else { + let lastTime: number = this._lastAppPlaySoundTime.get(path); + if (timenum - lastTime > this._appCanPlaySoundCutTime) { + this._lastAppPlaySoundTime.set(path, timenum); + let audioId: number = console.audioEngine.playEffect(this._idToAppClip.get(id), loop); + this._setAppAudioId(id, audioId); + } + } + } else { + console.error("未知的Sound Id: ", id); + } + } + + /** + * 停止音效 + * @param id + */ + public StopAppSound(id: number): void { + let audioId: number = this._getAppAudioId(id); + if (audioId >= 0) { + console.audioEngine.stopEffect(audioId); + } + } + + /** + * 打開音樂音量 + */ + public OpenMusic(): void { + super.OpenMusic(); + this._setAppMusicVolume(0.3); + } + /** + * 關閉音樂音量 + */ + public CloseMusic(): void { + super.CloseMusic(); + this._setAppMusicVolume(0.0); // 這邊再改改 + } + + /** + * 設定音樂音量 + * @param volume + */ + private _setAppMusicVolume(volume: number): void { + // 靜音後有一禎仍然會撥放的問題:背景音樂要回復 + if (this._currentAppMusic != -1 && volume > 0 && !console.audioEngine.isMusicPlaying()) { + this._ccAppMusicPlayId = console.audioEngine.playMusic(this._idToAppClip.get(this._currentAppMusic), true); + } + } + + /** + * 撥放音樂 + * @param id + * @param loop + */ + public PlayAppMusic(id: number, loop: boolean = true): void { + if (this._currentAppMusic != id) { + if (this._idToAppClip.has(id)) { + // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 + if (console.audioEngine.getMusicVolume() > 0) { + this._ccAppMusicPlayId = console.audioEngine.playMusic(this._idToAppClip.get(id), loop); + } + this._currentAppMusic = id; + } else { + console.error("未知的Music Id: ", id); + } + } + } + + private _ccAppMusicPlayId: number = -1; + private _currentAppMusicTime: number = -1; + + public pauseOrResume(isPause?: boolean): void { + super.pauseOrResume(); + if (isPause) { + this._currentAppMusicTime = console.audioEngine.getCurrentTime(this._ccAppMusicPlayId); + console.audioEngine.pauseAll(); + console.audioEngine.stopMusic(); + } else { + console.audioEngine.resumeAll(); + console.audioEngine.setCurrentTime(this._ccAppMusicPlayId, this._currentAppMusicTime); + } + } + + /** + * 停止音樂 + * @param id + */ + public StopMusic(): void { + console.audioEngine.stopMusic(); + this._currentAppMusic = -1; + } + +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Audio/CSCommonAudios.ts.meta b/src/script/Engine/Utils/Audio/CSCommonAudios.ts.meta new file mode 100644 index 0000000..bfb0744 --- /dev/null +++ b/src/script/Engine/Utils/Audio/CSCommonAudios.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "ce946cad-16db-4383-a734-43bb8f14089e", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Bezier.meta b/src/script/Engine/Utils/Bezier.meta new file mode 100644 index 0000000..e6eb2ec --- /dev/null +++ b/src/script/Engine/Utils/Bezier.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "4e2d4321-bbfb-46d8-87bc-15a7c99c000d", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Bezier/Bezier.ts b/src/script/Engine/Utils/Bezier/Bezier.ts new file mode 100644 index 0000000..e06affc --- /dev/null +++ b/src/script/Engine/Utils/Bezier/Bezier.ts @@ -0,0 +1,16 @@ +export module Bezier { + + export function GetPoint(p0: console.Vec2, p1: console.Vec2, p2: console.Vec2, p3: console.Vec2, t: number): console.Vec2 { + if (t < 0) { + t = 0; + } + else if (t > 1) { + t = 1 + } + let OneMinusT = 1 - t; + return p0.mul(OneMinusT * OneMinusT * OneMinusT) + .add(p1.mul(3 * OneMinusT * OneMinusT * t)) + .add(p2.mul(3 * OneMinusT * t * t)) + .add(p3.mul(t * t * t)); + } +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Bezier/Bezier.ts.meta b/src/script/Engine/Utils/Bezier/Bezier.ts.meta new file mode 100644 index 0000000..946290b --- /dev/null +++ b/src/script/Engine/Utils/Bezier/Bezier.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "b47d81c4-01a1-45cd-94f8-19daf96f17a8", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/CCExtensions.meta b/src/script/Engine/Utils/CCExtensions.meta new file mode 100644 index 0000000..b4ecd16 --- /dev/null +++ b/src/script/Engine/Utils/CCExtensions.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "dcb480f5-98b4-4a48-9d82-e3e1fe837e8d", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/CCExtensions/ArrayExtension.ts b/src/script/Engine/Utils/CCExtensions/ArrayExtension.ts new file mode 100644 index 0000000..84b4943 --- /dev/null +++ b/src/script/Engine/Utils/CCExtensions/ArrayExtension.ts @@ -0,0 +1,15 @@ +declare interface Array { + /** + * 移除一個值並且回傳 + * @param index + */ + ExRemoveAt(index: number): T; +} + +Array.prototype.ExRemoveAt || Object.defineProperty(Array.prototype, 'ExRemoveAt', { + enumerable: false, + value: function (index: number) { + let item = this.splice(index, 1); + return item[0]; + } +}) \ No newline at end of file diff --git a/src/script/Engine/Utils/CCExtensions/ArrayExtension.ts.meta b/src/script/Engine/Utils/CCExtensions/ArrayExtension.ts.meta new file mode 100644 index 0000000..d50500a --- /dev/null +++ b/src/script/Engine/Utils/CCExtensions/ArrayExtension.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "02aa6cd7-21a1-4c22-bcbe-296bb938badd", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/CCExtensions/CCExtension.ts b/src/script/Engine/Utils/CCExtensions/CCExtension.ts new file mode 100644 index 0000000..5966567 --- /dev/null +++ b/src/script/Engine/Utils/CCExtensions/CCExtension.ts @@ -0,0 +1,223 @@ +declare namespace cc { + + export interface Node { + /** + * 設定世界座標 + * @param worldPoint + */ + SetWorldPosition(worldPoint: console.Vec2): void; + /** + * 取得世界座標 + */ + GetWorldPosition(): console.Vec2; + /** + * 設定長寬 + * @param size + */ + SetSizeDelta(size: console.Vec2); + /** + * 取得長寬 + */ + GetSizeDelta(): console.Vec2; + /** + * 增加一個子物件 + * @param childObj + */ + ExAddChild(childObj: console.Prefab | console.Node, childActive?: boolean): console.Node; + + /**設定層級為最低層 */ + ExSetLowestOrder(): void; + + /**設定層級為最高層 */ + ExSetHighestOrder(): void; + + /**設定層級,比目標OBJ再低一層 */ + ExSetOrderUnderTheObj(obj: console.Node, isNew?: boolean): number; + + /**設定層級,比目標OBJ再高一層 */ + ExSetOrderOverTheObj(obj: console.Node, isNew?: boolean): number; + /**位置維持在原位 */ + ExSetParent(parentObj: console.Node): void; + ExSetGray(showGray: boolean): void; + } +} + +console.Node.prototype.SetWorldPosition || Object.defineProperty(console.Node.prototype, 'SetWorldPosition', { + enumerable: false, + value: function (cocosWorldPos: console.Vec2) { + // let cocosWorldPos = new console.Vec2(unityWorldPos.x + 711, unityWorldPos.y + 400); + this.setPosition(this.parent.convertToNodeSpaceAR(cocosWorldPos)); + } +}) +console.Node.prototype.GetWorldPosition || Object.defineProperty(console.Node.prototype, 'GetWorldPosition', { + enumerable: false, + value: function () { + let cocosWorldPos = this.parent.convertToWorldSpaceAR(this.position); + // let unityWorldPos = new console.Vec2(cocosWorldPos.x - 711, cocosWorldPos.y - 400); + return cocosWorldPos; + } +}) +console.Node.prototype.SetSizeDelta || Object.defineProperty(console.Node.prototype, 'SetSizeDelta', { + enumerable: false, + value: function (size: console.Vec2) { + this.setContentSize(size.x, size.y); + } +}) +console.Node.prototype.GetSizeDelta || Object.defineProperty(console.Node.prototype, 'GetSizeDelta', { + enumerable: false, + value: function () { + let size: console.Size = this.GetSizeDelta(); + return new console.Vec2(size.width, size.width); + } +}) +console.Node.prototype.ExAddChild || Object.defineProperty(console.Node.prototype, 'ExAddChild', { + enumerable: false, + value: function (childObj: console.Prefab | console.Node, childActive: boolean = true) { + let gameObj = null; + if (childObj instanceof console.Prefab) { + gameObj = console.instantiate(childObj); + } + else { + gameObj = console.instantiate(childObj); + } + gameObj.active = childActive ? true : childActive; + gameObj.parent = this; + return gameObj; + } +}) +console.Node.prototype.ExSetLowestOrder || Object.defineProperty(console.Node.prototype, 'ExSetLowestOrder', { + enumerable: false, + value: function () { + this.setSiblingIndex(0); + } +}) +console.Node.prototype.ExSetHighestOrder || Object.defineProperty(console.Node.prototype, 'ExSetHighestOrder', { + enumerable: false, + value: function () { + this.setSiblingIndex(Number.MAX_VALUE); + } +}) +console.Node.prototype.ExSetOrderUnderTheObj || Object.defineProperty(console.Node.prototype, 'ExSetOrderUnderTheObj', { + enumerable: false, + value: function (obj: console.Node, isNew?: boolean) { + + let newIndex: number; + let objIndex = obj.getSiblingIndex(); + + // 如果是新創的元件 + if (isNew) { + newIndex = objIndex; + } + // 如果是已經在場景上的元件 + else { + let myIndex = this.getSiblingIndex(); + + // 如果一開始就在它下面 + if (myIndex < objIndex) { + newIndex = objIndex - 1; + } + else { + newIndex = objIndex; + } + } + this.setSiblingIndex(newIndex); + return newIndex; + } +}) +console.Node.prototype.ExSetOrderOverTheObj || Object.defineProperty(console.Node.prototype, 'ExSetOrderOverTheObj', { + enumerable: false, + value: function (obj: console.Node, isNew?: boolean) { + let newIndex: number; + let objIndex = obj.getSiblingIndex(); + + // 如果是新創的元件 + if (isNew) { + newIndex = objIndex + 1; + } + // 如果是已經在場景上的元件 + else { + let myIndex = this.getSiblingIndex(); + + // 如果一開始就在它下面 + if (myIndex < objIndex) { + newIndex = objIndex; + } + else { + newIndex = objIndex + 1; + } + } + this.setSiblingIndex(newIndex); + return newIndex; + } +}) +console.Node.prototype.ExSetParent || Object.defineProperty(console.Node.prototype, 'ExSetParent', { + enumerable: false, + value: function (parentObj: console.Node) { + let oriPos = this.GetWorldPosition(); + this.setParent(parentObj); + this.SetWorldPosition(oriPos); + } +}) +console.Node.prototype.ExSetGray || Object.defineProperty(console.Node.prototype, 'ExSetGray', { + enumerable: false, + value: function (showGray: boolean): void { + let btn: console.Button = this.getComponent(console.Button); + if (btn) { + btn.interactable = !showGray; + } + let material: console.Material = console.Material.createWithBuiltin(showGray ? console.Material.BUILTIN_NAME.GRAY_SPRITE.toString() : console.Material.BUILTIN_NAME.SPRITE.toString(), 0); + !showGray && material.define("USE_TEXTURE", true, 0); + let spriteComs: any[] = this.getComponentsInChildren(console.Sprite).concat(this.getComponentsInChildren(console.Label)); + for (let sprite of spriteComs) { + sprite.setMaterial(0, material); + } + + // 先使用createWithBuiltin,如果材質球一直Create沒被刪除,會在修改。 + // let material: console.Material = console.Material.getBuiltinMaterial(showGray ? console.Material.BUILTIN_NAME.GRAY_SPRITE.toString() : console.Material.BUILTIN_NAME.SPRITE.toString()); + // for (let sprite of spriteComs) { + // if (showGray) { + // sprite.setMaterial(0, console.Material.getBuiltinMaterial('2d-gray-sprite')); + // } + // else { + // sprite.setMaterial(0, console.Material.getBuiltinMaterial('2d-sprite')); + // } + // } + }, +}); +// console.Node.prototype.SetWorldPosition = function (cocosWorldPos: console.Vec2): void { +// // let cocosWorldPos = new console.Vec2(unityWorldPos.x + 711, unityWorldPos.y + 400); +// this.setPosition(this.parent.convertToNodeSpaceAR(cocosWorldPos)); +// } +// console.Node.prototype.GetWorldPosition = function (): console.Vec2 { +// let cocosWorldPos = this.parent.convertToWorldSpaceAR(this.position); +// // let unityWorldPos = new console.Vec2(cocosWorldPos.x - 711, cocosWorldPos.y - 400); +// return cocosWorldPos; +// } + +// console.Node.prototype.SetSizeDelta = function (size: console.Vec2) { +// this.setContentSize(size.x, size.y); +// } +// console.Node.prototype.GetSizeDelta = function (): console.Vec2 { +// let size: console.Size = this.GetSizeDelta(); +// return new console.Vec2(size.width, size.width); +// } + +// console.Node.prototype.ExAddChild = function (childObj: console.Prefab | console.Node): console.Node { + +// let gameObj = null; +// if (childObj instanceof console.Prefab) { +// gameObj = console.instantiate(childObj); +// } +// else { +// gameObj = console.instantiate(childObj); +// } +// gameObj.parent = this; +// return gameObj; +// } + +// console.Node.prototype.ExSetLowestOrder = function (): void { +// this.setSiblingIndex(0); +// } +// console.Node.prototype.ExSetHighestOrder = function (): void { +// this.setSiblingIndex(Number.MAX_VALUE); +// } diff --git a/src/script/Engine/Utils/CCExtensions/CCExtension.ts.meta b/src/script/Engine/Utils/CCExtensions/CCExtension.ts.meta new file mode 100644 index 0000000..5d1f492 --- /dev/null +++ b/src/script/Engine/Utils/CCExtensions/CCExtension.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "b373f805-9297-4af5-8ea6-0a250649b5b0", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/CCExtensions/NumberExtension.ts b/src/script/Engine/Utils/CCExtensions/NumberExtension.ts new file mode 100644 index 0000000..a745286 --- /dev/null +++ b/src/script/Engine/Utils/CCExtensions/NumberExtension.ts @@ -0,0 +1,189 @@ + +declare interface Number { + + /** + * 金額每三位數(千)加逗號, 並且補到小數點第2位 + * 輸出 41,038,560.00 + * @param precision 補到小數點第幾位 + * @param isPadZero 是否要補零 + * */ + ExFormatNumberWithComma(precision?: number, isPadZero?: boolean): string; + /** + * 基本4位數(9,999-999B-T) + * */ + ExTransferToBMK(precision?: number,offset?: number): string; + /** + * 數字轉字串, 頭補0 + * @param size + */ + Pad(size: number): string; + /** + * 四捨五入到小數點第X位 (同server計算規則) + * @param precision + */ + ExToNumRoundDecimal(precision: number): number; + /** + * 無條件捨去到小數點第X位 + * @param precision + */ + ExToNumFloorDecimal(precision: number): number; + /** + * 無條件捨去強制保留X位小數,如:2,會在2後面補上00.即2.00 + * @param precision 補到小數點第幾位 + * @param isPadZero 是否要補零 + */ + ExToStringFloorDecimal(precision: number, isPadZero?: boolean): string; + /** + * 取整數) + */ + ExToInt():number; + /** + * 小數轉整數(支援科學符號) + */ + Float2Fixed():number; + /** + * 數字長度(支援科學符號) + */ + DigitLength():number; + + target: number; + + +} + +Number.prototype.ExFormatNumberWithComma || Object.defineProperty(Number.prototype, 'ExFormatNumberWithComma', { + enumerable: false, + value: function (precision: number = 2, isPadZero: boolean = true) { + + // let arr = String(this).split('.'); + let arr = this.ExToStringFloorDecimal(precision, isPadZero).split('.'); + let num = arr[0], result = ''; + while (num.length > 3) { + result = ',' + num.slice(-3) + result; + num = num.slice(0, num.length - 3); + } + if (num.length > 0) result = num + result; + return arr[1] ? result + '.' + arr[1] : result; + } +}) + + +Number.prototype.ExTransferToBMK || Object.defineProperty(Number.prototype, 'ExTransferToBMK', { + enumerable: false, + value: function (precision: number=2,offset: number = 0) { + /**千 */ + let MONEY_1K: number = 1000; + /**萬 */ + // let MONEY_10K: number = 10000; + /**十萬 */ + // let MONEY_100K: number = 100000; + /**百萬 */ + let MONEY_1M: number = 1000000; + /**千萬 */ + // let MONEY_10M: number = 10000000; + /**億 */ + // let MONEY_100M: number = 100000000; + /**十億 */ + let MONEY_1B: number = 1000000000; + /**百億 */ + // let MONEY_10B: number = 10000000000; + /**千億 */ + // let MONEY_100B: number = 100000000000; + /**兆 */ + // let MONEY_1T: number = 1000000000000; + offset = Math.pow(10, offset); + // if (this >= MONEY_1T * offset) { + // //(3)1,000T + // //1T~ + // return (~~(this / MONEY_1T)).ExFormatNumberWithComma(0) + "T"; + // } + if (this >= MONEY_1B * offset) { + //1,000B~900,000B + //1B~900B + return (this / MONEY_1B).ExFormatNumberWithComma(3, false) + "B"; + } + else if (this >= MONEY_1M * offset) { + //1,000M~900,000M + //1M~900M + return (this / MONEY_1M).ExFormatNumberWithComma(3, false) + "M"; + } + else if (this >= MONEY_1K * offset) { + //1,000K~900,000K + //1K~90K + return (this / MONEY_1K).ExFormatNumberWithComma(3, false) + "K"; + } + else { + //0~9,000,000 + //0~9,000 + return this.ExFormatNumberWithComma(precision); + } + } +}) +Number.prototype.Pad || Object.defineProperty(Number.prototype, 'Pad', { + enumerable: false, + value: function (size: number) { + let s = this + ""; + while (s.length < size) s = "0" + s; + return s; + } +}) +Number.prototype.ExToNumRoundDecimal || Object.defineProperty(Number.prototype, 'ExToNumRoundDecimal', { + enumerable: false, + value: function (precision: number) { + return Math.round(Math.round(this * Math.pow(10, (precision || 0) + 1)) / 10) / Math.pow(10, (precision || 0)); + } +}) +Number.prototype.ExToInt || Object.defineProperty(Number.prototype, 'ExToInt',{ + enumerable: false, + value: function (){ + return ~~this; + } +}) +Number.prototype.ExToNumFloorDecimal || Object.defineProperty(Number.prototype, 'ExToNumFloorDecimal', { + enumerable: false, + value: function (precision: number) { + let str = this.toPrecision(12); + let dotPos = str.indexOf('.'); + return dotPos == -1 ? this : +`${str.substr(0, dotPos + 1 + precision)}`; + } +}) +Number.prototype.ExToStringFloorDecimal || Object.defineProperty(Number.prototype, 'ExToStringFloorDecimal', { + enumerable: false, + value: function (precision: number, isPadZero: boolean = true) { + // 取小數點第X位 + let f = this.ExToNumFloorDecimal(precision); + let s = f.toString(); + // 補0 + if (isPadZero) { + let rs = s.indexOf('.'); + if (rs < 0) { + rs = s.length; + s += '.'; + } + while (s.length <= rs + precision) { + s += '0'; + } + } + return s; + } +}) +Number.prototype.Float2Fixed || Object.defineProperty(Number.prototype, 'Float2Fixed', { + enumerable: false, + value: function () { + if (this.toString().indexOf('e') === -1) { + return Number(this.toString().replace('.', '')); + } + const dLen = this.DigitLength(); + return dLen > 0 ? +parseFloat((this * Math.pow(10, dLen)).toPrecision(12)) : this; + } +}) +Number.prototype.DigitLength || Object.defineProperty(Number.prototype, 'DigitLength', { + enumerable: false, + value: function () { + const eSplit = this.toString().split(/[eE]/); + const len = (eSplit[0].split('.')[1] || '').length - (+(eSplit[1] || 0)); + return len > 0 ? len : 0; + } +}) + + \ No newline at end of file diff --git a/src/script/Engine/Utils/CCExtensions/NumberExtension.ts.meta b/src/script/Engine/Utils/CCExtensions/NumberExtension.ts.meta new file mode 100644 index 0000000..2216eef --- /dev/null +++ b/src/script/Engine/Utils/CCExtensions/NumberExtension.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "788e7381-bee6-4b74-addb-c4aa4c4ff4e3", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Number.meta b/src/script/Engine/Utils/Number.meta new file mode 100644 index 0000000..4c6cba6 --- /dev/null +++ b/src/script/Engine/Utils/Number.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "d6e55fc6-00b6-496a-aae2-74d694c1223b", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Number/NumberEx.ts b/src/script/Engine/Utils/Number/NumberEx.ts new file mode 100644 index 0000000..8b04bf5 --- /dev/null +++ b/src/script/Engine/Utils/Number/NumberEx.ts @@ -0,0 +1,191 @@ +import { CoroutineV2 } from "../../CatanEngine/CoroutineV2/CoroutineV2"; +import { RandomEx } from "./RandomEx"; + +export module NumberEx { + /** + * 數字滾動 + * @param startNum + * @param endNum + * @param callbackfn + * @param chabgeRate + */ + export function* ChangeScore(startNum: number, endNum: number, callbackfn: (num: number) => void, sec: number) { + let fps = 30; + let waitTime = 0.03; + let changeRate = sec * fps; // -1為了讓changeRate數字能混亂點 + changeRate = changeRate - 1 <= 0 ? changeRate : changeRate - 1; + changeRate = 1 / changeRate; + let diff = endNum - startNum; + let isIncrease = endNum >= startNum; + let tempScore = startNum; + let counter = 0; + let randomRate = 0; + while (true) { + if (endNum != tempScore) { + if (counter % 2 == 0) { + if (isIncrease) { randomRate = RandomEx.GetFloat(0, diff * changeRate).ExToNumFloorDecimal(2); } + else { randomRate = RandomEx.GetFloat(0, -diff * changeRate).ExToNumFloorDecimal(2); } + } + else { + randomRate = -randomRate; + } + + tempScore += diff * changeRate + randomRate; + // 遞增 + if (isIncrease && tempScore > endNum) { + tempScore = endNum; + } + // 遞減 + if (!isIncrease && tempScore < endNum) { + tempScore = endNum; + } + callbackfn(tempScore); + // yield null; + counter++; + yield CoroutineV2.WaitTime(waitTime); + } + else { + callbackfn(endNum); + break; + } + } + } + + /** + * 數字跳動 + * @param minNum 起始數字 + * @param maxNum 最終數字 + * @param callbackfn callbackfn + * @param sec 時間 + */ + export function* BeatScore(minNum: number, maxNum: number, endNum: number, callbackfn: (num: number) => void, sec: number): IterableIterator { + let fps: number = 13; + let waitTime: number = 0.07; + let changeRate: number = sec * fps; // -1為了讓changeRate數字能混亂點 + changeRate = changeRate - 1 <= 0 ? changeRate : changeRate - 1; + changeRate = 1 / changeRate; + let diff: number = maxNum - minNum; + let isIncrease: boolean = maxNum >= minNum; + let tempScore: number = minNum; + let counter: number = 0; + let randomRate: number = 0; + let lastNum: number = minNum; + let nowNum: number = minNum; + while (true) { + if (maxNum !== tempScore) { + if (counter % 2 === 0) { + if (isIncrease) { + randomRate = RandomEx.GetFloat(0, diff * changeRate).ExToNumFloorDecimal(2); + } else { + randomRate = RandomEx.GetFloat(0, -diff * changeRate).ExToNumFloorDecimal(2); + } + } else { + randomRate = -randomRate; + } + + tempScore += diff * changeRate + randomRate; + // 遞增 + if (isIncrease && tempScore > maxNum) { + tempScore = maxNum; + } + // 遞減 + if (!isIncrease && tempScore < maxNum) { + tempScore = maxNum; + } + while(nowNum === lastNum) { + nowNum = RandomEx.GetInt(minNum, maxNum + 1); + } + lastNum = nowNum; + callbackfn(nowNum); + // yield null; + counter++; + yield CoroutineV2.WaitTime(waitTime); + } else { + callbackfn(endNum); + break; + } + } + } + + /** + * 检测数字是否越界,如果越界给出提示 + * @param {*number} num 输入数 + */ + function checkBoundary(num: number) { + if (_boundaryCheckingState) { + if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { + console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`); + } + } + } + + /** + * 精确乘法 + */ + export function times(num1: number, num2: number, ...others: number[]): number { + if (others.length > 0) { + return times(times(num1, num2), others[0], ...others.slice(1)); + } + const num1Changed = num1.Float2Fixed(); + const num2Changed = num2.Float2Fixed(); + const baseNum = num1.DigitLength() + num2.DigitLength(); + const leftValue = num1Changed * num2Changed; + + checkBoundary(leftValue); + + return leftValue / Math.pow(10, baseNum); + } + + /** + * 精确加法 + */ + export function plus(num1: number, num2: number, ...others: number[]): number { + if (others.length > 0) { + return plus(plus(num1, num2), others[0], ...others.slice(1)); + } + const baseNum = Math.pow(10, Math.max(num1.DigitLength(), num2.DigitLength())); + return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; + } + + /** + * 精确减法 + */ + export function minus(num1: number, num2: number, ...others: number[]): number { + if (others.length > 0) { + return minus(minus(num1, num2), others[0], ...others.slice(1)); + } + const baseNum = Math.pow(10, Math.max(num1.DigitLength(), num2.DigitLength())); + return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; + } + + /** + * 精确除法 + */ + export function divide(num1: number, num2: number, ...others: number[]): number { + if (others.length > 0) { + return divide(divide(num1, num2), others[0], ...others.slice(1)); + } + const num1Changed = num1.Float2Fixed(); + const num2Changed = num2.Float2Fixed(); + checkBoundary(num1Changed); + checkBoundary(num2Changed); + return times((num1Changed / num2Changed), Math.pow(10, num2.DigitLength() - num1.DigitLength())); + } + + /** + * 四舍五入 + */ + export function round(num: number, ratio: number): number { + const base = Math.pow(10, ratio); + return divide(Math.round(times(num, base)), base); + } + + let _boundaryCheckingState = true; + /** + * 是否进行边界检查,默认开启 + * @param flag 标记开关,true 为开启,false 为关闭,默认为 true + */ + function enableBoundaryChecking(flag = true) { + _boundaryCheckingState = flag; + } +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Number/NumberEx.ts.meta b/src/script/Engine/Utils/Number/NumberEx.ts.meta new file mode 100644 index 0000000..63edb76 --- /dev/null +++ b/src/script/Engine/Utils/Number/NumberEx.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "363f5f7f-0623-4013-8571-0bb5c1dc95e6", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/Number/RandomEx.ts b/src/script/Engine/Utils/Number/RandomEx.ts new file mode 100644 index 0000000..236d683 --- /dev/null +++ b/src/script/Engine/Utils/Number/RandomEx.ts @@ -0,0 +1,42 @@ + +export module RandomEx { + + /** + * 取得隨機布林值 + */ + export function GetBool() { + return GetInt() >= 0; + } + /** + * 取得隨機整數(回傳min ~ max - 1) + * @param min + * @param max + */ + export function GetInt(min: number = Number.MIN_VALUE, max: number = Number.MAX_VALUE): number { + return Math.floor(Math.random() * (max - min)) + min; + } + /** + * 取得隨機小數 + * @param min + * @param max + */ + export function GetFloat(min: number = Number.MIN_VALUE, max: number = Number.MAX_VALUE): number { + return Math.random() * (max - min) + min; + } + /** + * 隨機取得複數個不重複回傳 + * @param num 取得數量 + * @param items 陣列 + */ + export function GetMultiNoRepeat(num: number, items: any[]): any[] { + let result: any[] = []; + for (let i: number = 0; i < num; i++) { + let ran: number = Math.floor(Math.random() * items.length); + let item = items.splice(ran, 1)[0]; + if (result.indexOf(item) == -1) { + result.push(item); + } + }; + return result; + } +} diff --git a/src/script/Engine/Utils/Number/RandomEx.ts.meta b/src/script/Engine/Utils/Number/RandomEx.ts.meta new file mode 100644 index 0000000..bcf2fa8 --- /dev/null +++ b/src/script/Engine/Utils/Number/RandomEx.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "ba4dee5b-ca5b-4435-a068-c4f5dd832bab", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/ScrollView.meta b/src/script/Engine/Utils/ScrollView.meta new file mode 100644 index 0000000..2b459b6 --- /dev/null +++ b/src/script/Engine/Utils/ScrollView.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.2", + "uuid": "f6471056-03d8-4d55-b039-6b62d056547c", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/ScrollView/UISuperItem.ts b/src/script/Engine/Utils/ScrollView/UISuperItem.ts new file mode 100644 index 0000000..9f50e93 --- /dev/null +++ b/src/script/Engine/Utils/ScrollView/UISuperItem.ts @@ -0,0 +1,379 @@ +/* + * @Author: steveJobs + * @Email: icipiqkm@gmail.com + * @Date: 2020-11-19 01:15:38 + * @Last Modified by: steveJobs + * @Last Modified time: 2020-12-04 14:41:01 + * @Description: Description + */ +import UISuperLayout, { UIChangeBrotherEvnet } from "./UISuperLayout"; +const { ccclass, property, menu } = console._decorator; +@ccclass +@menu("Plug-in/ScrollView/UISpuerItem") +export default class UISpuerItem extends console.Component { + private layout: UISuperLayout; + private brother: console.Node; + private originSize: console.Size; + private originScale: console.Vec2; + public index: number; + private remove: Function; + private _useScript: any = null; + /** 根据可视范围 和 一组item的个数 去掉 边距/间隔 来计算本item的真实宽度 */ + private get _width(): number { + if (this.layout.vertical) { + // 垂直滑动时 固定宽度 + return (this.layout.accommodWidth - this.layout.spacingWidth) / this.layout.column; + } else { + // 水平模式时 宽度随意 + return this.node.width * this.layout.getUsedScaleValue(this.node.scaleX); + } + } + /** 根据可视范围 和 一组item的个数 去掉 边距/间隔 来计算本item的真实高度 */ + private get _height(): number { + if (this.layout.horizontal) { + // 水平模式时 固定高度 + return (this.layout.accommodHeight - this.layout.spacingWidth) / this.layout.column; + } else { + // 垂直滑动时 高度随意 + return this.node.height * this.layout.getUsedScaleValue(this.node.scaleY); + } + } + onLoad(): void { + // 向node写入一个方法 省去了先获取组件然后调用的步骤 + this.node["watchSelf"] = this.watchSelf.bind(this); + this.node["saveOriginSize"] = this.SaveOriginSize.bind(this); + let widget: console.Widget = this.node.getComponent(console.Widget); + if (widget) { + console.warn("UISuperItem: item不允许挂console.Widget组件 请手动移除"); + this.node.removeComponent(widget); + } + } + + public SetInfo(index: number, remove: Function, ...iniData: any[]): void { + this.index = index; + this.remove = remove; + this._useScript.ImplementSet(...iniData); + } + private onRemove() { + this.remove(this.index); + } + private onClick() { + + } + public SaveOriginSize(): void { + this.originSize = console.size(this.node.width, this.node.height); + this.node.setContentSize(this.originSize); + this.originScale = console.v2(this.node.scaleX, this.node.scaleY); + } + public Init(layout: UISuperLayout, useScript: any): void { + this._useScript = useScript; + this.layout = layout; + this.layout.node.on(UIChangeBrotherEvnet, this.onChangeBrother, this); + this.SaveOriginSize(); + this.node.on(console.Node.EventType.SIZE_CHANGED, this.watchSize, this); + this.node.on(console.Node.EventType.SCALE_CHANGED, this.watchSize, this); + this.onChangeBrother(); + } + onDestroy(): void { + if (this.layout != null) { + this.layout.node.off(UIChangeBrotherEvnet, this.onChangeBrother, this); + } + this.node.off(console.Node.EventType.SIZE_CHANGED, this.watchSize, this); + this.node.off(console.Node.EventType.SCALE_CHANGED, this.watchSize, this); + this.unlisten(); + } + /** + * 当兄弟节点的顺序变化时 来改变自己监听的对象 + * 0,1,2,3,4,5,6,7,8,9 例如列表中共有10个item 0是header 9是footer + * 正序排列时 监听的顺序是 9->8->7->6->5->4->3->2->1->0 0的 brother=null + * 向下填充的逻辑是 0跑到9后面 0=footer 0的brother=9 相对9的位置设置自己 此时1=header + * 向上填充的逻辑是 9跑到0前面 此时9=header 9的brother=null 主动设置自己相对于0前面位置之后 0的brother=9 8=footer + */ + private onChangeBrother() { + let brother: console.Node = this.layout.getBrotherNode(this.node); // 获取我应该监听的那个兄弟 + if (brother?.uuid === this.brother?.uuid) { + return; // 如果没有变化 则跳过 + } + this.unlisten(); // 我的兄弟换人了?先移除我原来的 + this.brother = brother; // 他是我的兄弟 + this.listen(); // 监听他 + this.watchBrother(); // 相对兄弟节点来设置自己的位置 + } + private listen() { + this.brother?.on("leave", this.unlisten, this); + this.brother?.on(console.Node.EventType.POSITION_CHANGED, this.watchBrother, this); + } + private unlisten() { + this.brother?.off("leave", this.unlisten, this); + this.brother?.off(console.Node.EventType.POSITION_CHANGED, this.watchBrother, this); + this.brother = null; + } + /** 当我的尺寸/缩放改变时 */ + private watchSize() { + if (this.layout.column > 1) { // 如果是Grid模式 不允许修改尺寸/缩放 强制改回来 + this.node.setContentSize(this.originSize); + this.node.setScale(this.originScale); + } else { + if (this.layout.vertical && (this.node.getContentSize().width != this.originSize.width || this.node.scaleX != this.originScale.x)) { + this.node.width = this.originSize.width; + this.node.scaleX = this.originScale.x; + + } else if (this.layout.horizontal && (this.node.getContentSize().height != this.originSize.height || this.node.scaleY != this.originScale.y)) { + this.node.height = this.originSize.height; + this.node.scaleY = this.originScale.y; + } + // 如果我监听了兄弟节点就设置自己相对兄弟节点的位置,否则 我就发送一个位置变化的消息 让监听我的兄弟相对我做出变化 + this.brother && this.watchBrother(); + this.layout.resetScrollView(); + this.node.emit(console.Node.EventType.POSITION_CHANGED); + } + if (this.node["index"] == 0 && this.layout.isNormalSize) { + this.node.setPosition(this.layout.getGroupHeader(this.node)); + } + } + // 设置自己相对于上一个兄弟节点的位置 + public watchBrother() { + if (!this.brother) { return } + if (this.layout.headerToFooter) { // 正序排列时 + this.headerToFooterRelativeToFooter(this.brother); + } else {// 倒序排列时 + this.footerToHeaderRelativeToFooter(this.brother); + } + } + private isOutOfBoundary(offset: console.Vec2) { + if (this.layout.vertical && offset.y == 0) { return true } + if (this.layout.horizontal && offset.x == 0) { return true } + return false; + } + /** 从下到上排序方向 检查头部是否需要向上填充 */ + private footerToHeaderWatchHeader() { + // 如果不是头部一组的任意一个时跳过 比如一组有3个item 只计算 0,1,2 + if (this.layout.getSiblingIndex(this.node) >= this.layout.column) { return } + // 如果此时【尾部】已经是最后一个数据时 + let index = this.layout.footer["index"] + 1; + if (index >= this.layout.maxItemTotal) { + if (!this.layout.footerLoop || this.layout.scrollToHeaderOrFooter) { return } + index = 0; + } + // 计算超出的偏移量 (从下到上排序方向时 头部在 下尾部在上 检测【头部】是否超出下边框) + let offset = this.layout.isOutOfBoundaryFooter(this.node); + // 没有超出时跳过 + if (!this.isOutOfBoundary(offset)) { return } + // 将自己的数据索引 + 1 + this.node["index"] = index; + // 发送通知到应用层 刷新显示 + this.layout.notifyRefreshItem(this.node); + // 发给监听我的节点 通知我离开了 移除对我的所有监听 + this.node.emit("leave"); + // 将自己的节点索引设置到尾部 + this.layout.setSiblingIndex(this.node, this.layout.children.length - 1); + } + /** 从下到上排序方向 检查尾部是否需要向下填充 */ + private footerToHeaderWatchFooter() { + // 如果不是尾部一组的任意一个时跳过 比如一组有3个item 只计算末尾的3个item + if (this.layout.getSiblingIndex(this.node) < this.layout.children.length - this.layout.column) { return } + // 如果此时【头部】已经是第一个数据时 + let index = this.layout.header["index"] - 1; + if (index < 0) { + // 如果没有使用无限循环功能 否则不往下走 + if (!this.layout.headerLoop || this.layout.scrollToHeaderOrFooter) { return } + index = this.node["index"]; + } + // 计算超出的偏移量 (从下到上排序方向时 头部在 下尾部在上 检测【尾部】是否超出下边框) + let offset = this.layout.isOutOfBoundaryHeader(this.node); + // 没有超出时跳过 + if (!this.isOutOfBoundary(offset)) { return } + // 将自己的数据索引 - 1 + this.node["index"] = index; + // 发送通知到应用层 刷新显示 + this.layout.notifyRefreshItem(this.node); + // 发给监听我的兄弟 通知我离开了 移除对我的所有监听 + this.node.emit("leave"); + // 因为我是尾部 我监听了别人,此时移除我的所有监听 因为我马上就要成为老大 老大不需要监听任何人 + this.unlisten(); + // 因为我是老大 我不能相对别人来设置自己的相对位置,所以我需要主动设置自己(相对上一个老大的位置来设置自己) 别人都会相对我的位置做出变化 + this.footerToHeaderRelativeToHeader(this.layout.header); + // 将自己的节点索引设置到头部 + this.layout.setSiblingIndex(this.node, 0); + } + /** 从上到下排序方向 检查头部是否需要向下填充 */ + private headerToFooterWatchHeader() { + // 如果不是头部一组的任意一个时跳过 比如一组有3个item 只计算 0,1,2 + if (this.layout.getSiblingIndex(this.node) >= this.layout.column) { return } + // 如果此时【尾部】已经是第一个数据时 + let index = this.layout.footer["index"] + 1; + if (index > this.layout.maxItemTotal - 1) { + // 如果没有使用无限循环功能 否则不往下走 + if (!this.layout.footerLoop || this.layout.scrollToHeaderOrFooter) { return } + index = 0; + } + // 计算超出的偏移量 (从下到上排序方向时 头部在下 尾部在上 检测【尾部】是否超出下边框) + let offset = this.layout.isOutOfBoundaryHeader(this.node); + // 没有超出时跳过 + if (!this.isOutOfBoundary(offset)) { return } + // 将自己的数据索引 + 1 + this.node["index"] = index; + // 发送通知到应用层 刷新显示 + this.layout.notifyRefreshItem(this.node); + // 发给监听我的兄弟 通知我离开了 移除对我的所有监听 + this.node.emit("leave"); + // 将自己的节点索引设置到尾部 + this.layout.setSiblingIndex(this.node, this.layout.children.length - 1); + } + /** 从上到下排序方向 检查尾部是否需要向上填充 */ + private headerToFooterWatchFooter() { + // 如果不是尾部一组的任意一个时跳过 比如一组有3个item 只计算末尾的3个item + if (this.layout.getSiblingIndex(this.node) < this.layout.children.length - this.layout.column) { return } + // 如果此时【头部】已经是第一个数据时 + let index = this.layout.header["index"] - 1; + if (index < 0) { + // 如果没有使用无限循环功能 否则不往下走 + if (!this.layout.headerLoop || this.layout.scrollToHeaderOrFooter) { return } + index = this.node["index"]; + } + // 计算超出的偏移量 (从上到下排序方向时 头部在上 尾部在下 检测【尾部】是否超出下边框) + let offset = this.layout.isOutOfBoundaryFooter(this.node); + // 没有超出时跳过 + if (!this.isOutOfBoundary(offset)) { return } + // 将自己的数据索引 - 1 + this.node["index"] = index; + // 发送通知到应用层 刷新显示 + this.layout.notifyRefreshItem(this.node); + // 发给监听我的兄弟 通知我离开了 移除对我的所有监听 + this.node.emit("leave"); + // 因为我是尾部 我监听了别人,此时移除我的所有监听 因为我马上就要成为老大 老大不需要监听任何人 + this.unlisten(); + // 因为我是老大 我不能相对别人来设置自己的相对位置,所以我需要主动设置自己(相对上一个老大的位置来设置自己) 别人都会相对我的位置做出变化 + this.headerToFooterRelativeToHeader(this.layout.header); + // 将自己的节点索引设置到尾部 + this.layout.setSiblingIndex(this.node, 0); + } + /** isScrollToFooter=true 向下滑动 */ + public watchSelf(isScrollToFooter: boolean) { + if (isScrollToFooter) { + if (this.layout.headerToFooter) { + // 从【上到下排序】方向 检查【尾部】是否需要向上填充 + this.headerToFooterWatchFooter(); + } else { + // 从【下到上排序】方向 检查【头部】是否需要向上填充 + this.footerToHeaderWatchHeader(); + } + } else { + if (this.layout.headerToFooter) { + // 从【上到下排序】方向 检查【头部】是否需要向下填充 + this.headerToFooterWatchHeader(); + } else { + // 从【下到上排序】方向 检查【尾部】是否需要向下填充 + this.footerToHeaderWatchFooter(); + } + } + } + /** 从下到上 从右到左 排序方向 设置自己到相对node的头部 */ + private footerToHeaderRelativeToHeader(relative: console.Node) { + let pos = this.node.getPosition(); + // 从下到上 + if (this.layout.vertical) { + if (this.layout.isGroupHeader(relative)) { + pos.x = this.layout.getGroupFooter(this.node).x; + pos.y = this.layout.getGroupBottomY(this.node, relative); + } else { + pos.x = this.layout.getGroupLeftX(this.node, relative); + pos.y = relative.y; + } + if (this.node["index"] == 0) { + pos.x = this.layout.getGroupHeader(this.node).x; + } + } else { + // 从右到左 + if (this.layout.isGroupHeader(relative)) { + pos.x = this.layout.getGroupRightX(this.node, relative); + pos.y = this.layout.getGroupFooter(this.node).y; + } else { + pos.x = relative.x; + pos.y = this.layout.getGroupTopY(this.node, relative); + } + if (this.node["index"] == 0) { + pos.y = this.layout.getGroupHeader(this.node).y; + } + } + this.node.setPosition(pos); + } + /** 从下到上 从右到左 排序方向 设置自己到相对node的尾部 */ + private footerToHeaderRelativeToFooter(relative: console.Node) { + let pos = this.node.getPosition(); + // 从下到上 + if (this.layout.vertical) { + if (this.layout.isGroupFooter(relative)) { + pos.x = this.layout.getGroupHeader(this.node).x; + pos.y = this.layout.getGroupTopY(this.node, relative); + } else { + pos.x = this.layout.getGroupRightX(this.node, relative); + pos.y = relative.y; + } + } else { + // 从右到左 + if (this.layout.isGroupFooter(relative)) { + pos.x = this.layout.getGroupLeftX(this.node, relative); + pos.y = this.layout.getGroupHeader(this.node).y; + } else { + pos.x = relative.x; + pos.y = this.layout.getGroupBottomY(this.node, relative); + } + } + this.node.setPosition(pos); + } + /** 从上到下 从左到右 排序方向 设置自己到相对node的头部 */ + private headerToFooterRelativeToHeader(relative: console.Node) { + let pos = this.node.getPosition(); + // 从上到下 + if (this.layout.vertical) { + if (this.layout.isGroupHeader(relative)) { + pos.x = this.layout.getGroupFooter(this.node).x; + pos.y = this.layout.getGroupTopY(this.node, relative); + } else { + pos.x = this.layout.getGroupLeftX(this.node, relative); + pos.y = relative.y; + } + if (this.node["index"] == 0) { + pos.x = this.layout.getGroupHeader(this.node).x; + } + } else { + // 从左到右 + if (this.layout.isGroupHeader(relative)) { + pos.x = this.layout.getGroupLeftX(this.node, relative); + pos.y = this.layout.getGroupFooter(this.node).y; + } else { + pos.x = relative.x; + pos.y = this.layout.getGroupTopY(this.node, relative); + } + if (this.node["index"] == 0) { + pos.y = this.layout.getGroupHeader(this.node).y; + } + } + this.node.setPosition(pos); + } + /** 从上到下 从左到右 排序方向 设置自己到相对node尾部 */ + private headerToFooterRelativeToFooter(relative: console.Node) { + let pos = this.node.getPosition(); + // 从上到下 + if (this.layout.vertical) { + if (this.layout.isGroupFooter(relative)) { + pos.x = this.layout.getGroupHeader(this.node).x; + pos.y = this.layout.getGroupBottomY(this.node, relative); + } else { + pos.x = this.layout.getGroupRightX(this.node, relative); + pos.y = relative.y; + } + } else { + // 从左到右 + if (this.layout.isGroupFooter(relative)) { + pos.x = this.layout.getGroupRightX(this.node, relative); + pos.y = this.layout.getGroupHeader(this.node).y; + } else { + pos.x = relative.x; + pos.y = this.layout.getGroupBottomY(this.node, relative); + } + } + this.node.setPosition(pos); + } +} diff --git a/src/script/Engine/Utils/ScrollView/UISuperItem.ts.meta b/src/script/Engine/Utils/ScrollView/UISuperItem.ts.meta new file mode 100644 index 0000000..55d2f86 --- /dev/null +++ b/src/script/Engine/Utils/ScrollView/UISuperItem.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "486070ed-7155-4fa6-8cc4-81695cc3b28b", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/ScrollView/UISuperLayout.ts b/src/script/Engine/Utils/ScrollView/UISuperLayout.ts new file mode 100644 index 0000000..360026e --- /dev/null +++ b/src/script/Engine/Utils/ScrollView/UISuperLayout.ts @@ -0,0 +1,720 @@ +import UISpuerItem from "./UISuperItem"; +import UISpuerScrollView from "./UISuperScrollView"; +const { ccclass, property, menu } = console._decorator; +const EPSILON: number = 1e-4; +export const UIChangeBrotherEvnet = "UIChangeBrotherEvnet"; +export enum UISuperAxis { + HORIZONTAL = 0, + VERTICAL = 1 +} +export enum UISuperDirection { + HEADER_TO_FOOTER = 0, + FOOTER_TO_HEADER = 1, +} +@ccclass +@menu("Plug-in/ScrollView/UISuperLayout") +export default class UISuperLayout extends console.Component { + @property({ type: console.Enum(UISuperAxis), displayName: "排列方向" }) + public StartAxis: UISuperAxis = UISuperAxis.VERTICAL; + @property({ type: console.Enum(UISuperDirection), displayName: "排列子节点的方向" }) direction: UISuperDirection = UISuperDirection.HEADER_TO_FOOTER; + @property({ displayName: "上边距" }) paddingTop: number = 0; + @property({ displayName: "下边距" }) paddingBottom: number = 0; + @property({ displayName: "左边距" }) paddingLeft: number = 0; + @property({ displayName: "右边距" }) paddingRight: number = 0; + @property({ displayName: "间隔" }) spacing: console.Vec2 = console.Vec2.ZERO; + @property({ displayName: "每组item个数", tooltip: "单行的列数 或 单列的行数" }) column: number = 2; + @property({ displayName: "item创建倍率", tooltip: "相对于view的尺寸 默认2倍" }) multiple: number = 2; + @property({ type: console.Prefab, displayName: "item Prefab" }) prefab: console.Prefab = null; + @property({ displayName: "头部滑动循环" }) headerLoop: boolean = false; + @property({ displayName: "尾部滑动循环" }) footerLoop: boolean = false; + @property affectedByScale: boolean = true; + @property(console.Component.EventHandler) refreshItemEvents: console.Component.EventHandler[] = []; + private _gener: Generator; + private _isinited: boolean = false; + private _maxPrefabTotal: number = 0; + private _children: console.Node[] = []; // 和this.node.children 保持同步 + private _viewSize: console.Size; + private _scrollView: UISpuerScrollView = null; + private _maxItemTotal: number = 0; + private _prevLayoutPosition: console.Vec2 = console.Vec2.ZERO; + /** 当前的滚动是否是由 scrollTo 方法执行的 和touch滑动做个区分 */ + public scrollToHeaderOrFooter: boolean = false; + /** 根据上一次和本次的坐标变化计算滑动方向 */ + private get layoutDirection(): console.Vec2 { + let pos = console.Vec2.ZERO; + if (this.vertical) { + pos.y = this.node.y - this._prevLayoutPosition.y; + } else { + pos.x = this.node.x - this._prevLayoutPosition.x; + } + this._prevLayoutPosition = this.node.getPosition(); + return pos; + } + /** 是否是向下滑动 */ + private get isScrollToFooter(): boolean { + if (this.vertical) { + return this.layoutDirection.y < 0; + } else { + return this.layoutDirection.x > 0; + } + } + /** 自己维护的子节点数组 和this.node.children 保持同步 */ + public get children() { return this._children; } + /** 最大数据总数 */ + public get maxItemTotal() { return this._maxItemTotal; } + /** 当前被创建的item总数 */ + public get maxPrefabTotal() { return this._maxPrefabTotal; } + /** scrollView.view尺寸 */ + public get viewSize(): console.Size { + return this.scrollView.view.getContentSize(); + } + /** 是否是垂直模式 */ + public get vertical(): boolean { + return this.StartAxis == UISuperAxis.VERTICAL; + } + /** 是否是水平模式 */ + public get horizontal(): boolean { + return this.StartAxis == UISuperAxis.HORIZONTAL; + } + /** 是否是正序排列 */ + public get headerToFooter(): boolean { + return this.direction == UISuperDirection.HEADER_TO_FOOTER; + } + /** 是否是倒序排列 */ + public get footerToHeader(): boolean { + return this.direction == UISuperDirection.FOOTER_TO_HEADER; + } + /** 水平间隔总宽度 (Grid 模式返回多个间隔总宽度) */ + public get spacingWidth() { + return this.spacing.x * (this.column - 1); + } + /** 水平间隔总高度 (Grid 模式返回多个间隔总高度) */ + public get spacingHeight() { + return this.spacing.y * (this.column - 1); + } + /** 可容纳item的真实宽度 */ + public get accommodWidth() { + return this.viewSize.width - this.paddingLeft - this.paddingRight; + } + /** 可容纳item的真实高度 */ + public get accommodHeight() { + return this.viewSize.height - this.paddingTop - this.paddingBottom; + } + public get scrollView(): UISpuerScrollView { + if (!this._scrollView) { this._scrollView = this.node.parent.parent.getComponent(UISpuerScrollView); } + return this._scrollView; + } + /** 当前头部的item */ + public get header(): console.Node { + return this._children[0]; + } + /** 当前尾部的item */ + public get footer(): console.Node { + return this._children[this._children.length - 1]; + } + /** 真实的上边距 */ + public get topBoundary() { + if (this.headerToFooter) { + return this.headerBoundaryY + this.paddingTop; + } else { + return this.footerBoundaryY + this.paddingTop; + } + } + /** 真实的下边距 */ + public get bottomBoundary() { + if (this.headerToFooter) { + return this.footerBoundaryY - this.paddingBottom; + } else { + return this.headerBoundaryY - this.paddingBottom; + } + } + /** 真实的左边距 */ + public get leftBoundary() { + if (this.headerToFooter) { + return this.headerBoundaryX - this.paddingLeft; + } else { + return this.footerBoundaryX - this.paddingLeft; + } + } + /** 真实的右边距 */ + public get rightBoundary() { + if (this.headerToFooter) { + return this.footerBoundaryX + this.paddingRight; + } else { + return this.headerBoundaryX + this.paddingRight; + } + } + /** 头部item的世界坐标边框 类似 xMin、xMax */ + public get headerBoundaryX() { + if (this.headerToFooter) { + return this.node.x + this.header.x - this.header.anchorX * this.getScaleWidth(this.header); + } else { + return this.node.x + this.header.x + (1 - this.header.anchorX) * this.getScaleWidth(this.header); + } + } + /** 头部item的世界坐标边框 类似 yMin、yMax */ + public get headerBoundaryY() { + if (this.headerToFooter) { + return this.node.y + this.header.y + (1 - this.header.anchorY) * this.getScaleHeight(this.header); + } else { + return this.node.y + this.header.y - this.header.anchorY * this.getScaleHeight(this.header); + } + } + /** 尾部item的世界坐标边框 类似 xMin、xMax */ + public get footerBoundaryX() { + if (this.headerToFooter) { + return this.node.x + this.footer.x + (1 - this.footer.anchorX) * this.getScaleWidth(this.footer); + } else { + return this.node.x + this.footer.x - this.footer.anchorX * this.getScaleWidth(this.footer); + } + } + /** 尾部item的世界坐标边框 类似 yMin、yMax */ + public get footerBoundaryY() { + if (this.headerToFooter) { + return this.node.y + this.footer.y - this.footer.anchorY * this.getScaleHeight(this.footer); + } else { + return this.node.y + this.footer.y + (1 - this.footer.anchorY) * this.getScaleHeight(this.footer); + } + } + public get isNormalSize(): boolean { + return this.node.getContentSize().equals(this.viewSize); + } + + /** 重写 this.node.getContentSize 动态计算头尾item 返回虚拟的尺寸 非content设置的尺寸 */ + public getContentSize() { + let size = this.getReallySize(); + let viewSize = this.scrollView.view.getContentSize(); + // 列表为空时 直接返回 scrollView.view 的尺寸 + if (size.height < viewSize.height) { + size.height = viewSize.height; + } + if (size.width < viewSize.width) { + size.width = viewSize.width; + } + return size; + } + /** 返回 header到 footer 之间的整体尺寸 */ + public getReallySize() { + if (this.node.childrenCount == 0) { return this.viewSize; } + let size = console.Size.ZERO; + if (this.headerToFooter) { // 根据header和footer计算出真实的content尺寸 + size.width = this.footerBoundaryX + -this.headerBoundaryX + this.paddingLeft + this.paddingRight; + size.height = this.headerBoundaryY + -this.footerBoundaryY + this.paddingTop + this.paddingBottom; + } else { + size.width = this.headerBoundaryX + -this.footerBoundaryX + this.paddingLeft + this.paddingRight; + size.height = this.footerBoundaryY + -this.headerBoundaryY + this.paddingTop + this.paddingBottom; + } + return size; + } + /** 重置scrollview */ + public resetScrollView() { + this.scrollView.reset(); + } + /** 获取缩放系数 */ + public getUsedScaleValue(value: number) { + return this.affectedByScale ? Math.abs(value) : 1; + } + /** 设置最大item数量 */ + public async CreateItem(...iniData: any[]) { + this.scrollView.stopAutoScroll(); + this.scrollView.release(); // 释放(功能用于上拉加载 下拉刷新) + this.initlized(); // 初始化 + await this.asyncCreateItem(iniData); // 分帧创建item + let dataOffset = this.getDataOffset(iniData[0]); // 获取数据偏移量(根据value相对于 _maxItemTotal 计算增加、减少的数量) + let reallyOffset = this.getReallyOffset(dataOffset); // 获取真实的数据偏移(Grid模式 功能用于判断是否需要偏移header来将下方填满) + this.refreshItems(iniData[0], reallyOffset); // 通过已有的item['index'] 加上数据偏移 来是刷新显示 + this._maxItemTotal = iniData[0]; // 记录当前总数 + } + /** 获取兄弟节点 */ + public getBrotherNode(node: console.Node) { + let index = this.getSiblingIndex(node) - 1; // 此 getSiblingIndex 非 this.node.getSiblingIndex + return this._children[index]; + } + /** 是否是一组item中第一个(垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public isGroupHeader(node: console.Node): boolean { + let xOry = this.getGroupHeader(node); + let pos = this.vertical ? console.v2(xOry.x, 0) : console.v2(0, xOry.y); + let self = this.vertical ? console.v2(node.x, 0) : console.v2(0, node.y); + return self.fuzzyEquals(pos, EPSILON); + } + /** 是否是一组item中最后一个(垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public isGroupFooter(node: console.Node): boolean { + let xOry = this.getGroupFooter(node); + let pos = this.vertical ? console.v2(xOry.x, 0) : console.v2(0, xOry.y); + let self = this.vertical ? console.v2(node.x, 0) : console.v2(0, node.y); + return self.fuzzyEquals(pos, EPSILON); + } + /** 获取一组item中起始位置 (垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public getGroupHeader(node: console.Node): console.Vec2 { + let pos = console.Vec2.ZERO; + if (!node) { return pos; } + if (this.vertical) { + if (this.headerToFooter) { + pos.x = node.anchorX * this.getScaleWidth(node) + (this.paddingLeft * node.scaleX) - (this.node.anchorX * this.viewSize.width * node.scaleX); + pos.y = (1 - node.anchorY) * -this.getScaleHeight(node) - this.paddingTop + (1 - this.node.anchorY) * this.viewSize.height; + } else { + pos.x = node.anchorX * this.getScaleWidth(node) + this.paddingLeft - this.node.anchorX * this.viewSize.width; + pos.y = node.anchorY * this.getScaleHeight(node) + this.paddingBottom - this.node.anchorY * this.viewSize.height; + } + } else { + if (this.headerToFooter) { + pos.x = node.anchorX * this.getScaleWidth(node) + this.paddingLeft - this.node.anchorX * this.viewSize.width; + pos.y = (1 - node.anchorY) * -node.height - this.paddingTop + (1 - this.node.anchorY) * this.viewSize.height; + } else { + pos.x = this.accommodWidth * this.node.anchorX - this.getScaleWidth(node) * (1 - node.anchorX); + pos.y = (1 - node.anchorY) * -node.height - this.paddingTop + (1 - this.node.anchorY) * this.viewSize.height; + } + } + return pos; + } + /** 获取一组item中结束位置 (垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public getGroupFooter(node: console.Node): console.Vec2 { + let pos = console.Vec2.ZERO; + if (!node) { return pos; } + if (this.vertical) { + pos.x = (this.accommodWidth + this.paddingLeft) * this.node.anchorX - (this.getScaleWidth(node) * (1 - node.anchorX) + this.node.anchorX * this.paddingRight); + pos.y = node.y; + } else { + pos.x = node.x; + pos.y = -((this.accommodHeight + this.paddingTop) * this.node.anchorY - this.getScaleHeight(node) * node.anchorY) + (1 - node.anchorY) * this.paddingBottom; + } + return pos; + } + /** 获取一组item中 node 相对 relative 右偏移量 (垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public getGroupRightX(node: console.Node, relative: console.Node) { + if (!node || !relative) { return this.getGroupHeader(node).x; } + let prevWidth = relative.x + this.getScaleWidth(relative) * (1 - relative.anchorX); + let selfWidth = this.getScaleWidth(node) * node.anchorX; + return prevWidth + selfWidth + this.spacing.x; + } + /** 获取一组item中 node 相对 relative 左偏移量 (垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public getGroupLeftX(node: console.Node, relative: console.Node) { + if (!node || !relative) { return this.getGroupFooter(node).x; } + let prevWidth = relative.x - this.getScaleWidth(relative) * relative.anchorX; + let selfWidth = this.getScaleWidth(node) * (1 - node.anchorX); + return prevWidth - selfWidth - this.spacing.x; + } + /** 获取一组item中 node 相对 relative 下偏移量 (垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public getGroupBottomY(node: console.Node, relative: console.Node) { + let prevHeight = relative.y - this.getScaleHeight(relative) * relative.anchorY; + let selfHeight = this.getScaleHeight(node) * (1 - node.anchorY); + return prevHeight - selfHeight - this.spacing.y; + } + /** 获取一组item中 node 相对 relative 上偏移量 (垂直滑动中 一组item 就是单行的所有列 、水平滑动中 一组item 就是单列中所有行)*/ + public getGroupTopY(node: console.Node, relative: console.Node) { + let prevHeight = relative.y + this.getScaleHeight(relative) * (1 - relative.anchorY); + let selfHeight = this.getScaleHeight(node) * node.anchorY; + return prevHeight + selfHeight + this.spacing.y; + } + /** 判断给定的 node 乘以 multiple 倍数后 是否超出了头部边框 ( multiple = 1 就是一个node的尺寸 默认1.5倍)*/ + public isOutOfBoundaryHeader(node: console.Node, multiple: number = 1.5) { + let width = node.width * this.getUsedScaleValue(node.scaleX) * multiple; + let height = -node.height * this.getUsedScaleValue(node.scaleY) * multiple; + let offset = this.scrollView.getHowMuchOutOfBoundary(console.v2(width, height)); + return offset; + } + /** 判断给定的 node 乘以 multiple 倍数后 是否超出了尾部部边框 ( multiple = 1 就是一个node的尺寸 默认1.5倍)*/ + public isOutOfBoundaryFooter(node: console.Node, multiple: number = 1.5) { + let width = -node.width * this.getUsedScaleValue(node.scaleX) * multiple; + let height = node.height * this.getUsedScaleValue(node.scaleY) * multiple; + let offset = this.scrollView.getHowMuchOutOfBoundary(console.v2(width, height)); + return offset; + } + /** 滚动到头部 (根据 排列方向、排列子节点的方向)来调用 scrollView.scrollTo... 方法 */ + public scrollToHeader(timeInSecond?: number, attenuated?: boolean) { + this.scrollToHeaderOrFooter = timeInSecond > 0; + this.scrollView.stopAutoScroll(); + this.resetToHeader(); + if (this.headerToFooter) { + if (this.vertical) { + this.scrollView.scrollToTop(timeInSecond, attenuated); + } else { + this.scrollView.scrollToLeft(timeInSecond, attenuated); + } + } else { + if (this.vertical) { + this.scrollView.scrollToBottom(timeInSecond, attenuated); + } else { + this.scrollView.scrollToRight(timeInSecond, attenuated); + } + } + } + /** 滚动到尾部(根据 排列方向、排列子节点的方向)来调用 scrollView.scrollTo... 方法 */ + public scrollToFooter(timeInSecond?: number, attenuated?: boolean) { + this.scrollToHeaderOrFooter = timeInSecond > 0; + this.scrollView.stopAutoScroll(); + this.resetToFooter(); + if (this.headerToFooter) { + if (this.vertical) { + this.scrollView.scrollToBottom(timeInSecond, attenuated); + } else { + this.scrollView.scrollToRight(timeInSecond, attenuated); + } + } else { + if (this.vertical) { + this.scrollView.scrollToTop(timeInSecond, attenuated); + } else { + this.scrollView.scrollToLeft(timeInSecond, attenuated); + } + } + } + /** 通知给定的node刷新数据 */ + public notifyRefreshItem(target: console.Node) { + console.Component.EventHandler.emitEvents(this.refreshItemEvents, target, target["index"]); + } + /** 获取节点索引 */ + public getSiblingIndex(node: console.Node) { + return this._children.indexOf(node); + } + /** 自定义索引方法 这里不是通过实时修改节点索引的方法,只是模拟类似的功能,实际上并没有真正改变节点的实际顺序(优化项) */ + public setSiblingIndex(node: console.Node, index: number) { + // 此方法时参考引擎原setSiblingIndex方法 去掉了修改节点索引位置的调用(item本身的zIndex没有任何变化) + index = index !== -1 ? index : this._children.length - 1; + var oldIndex = this._children.indexOf(node); + if (index !== oldIndex) { + this._children.splice(oldIndex, 1); + if (index < this._children.length) { + this._children.splice(index, 0, node); + } else { + this._children.push(node); + } + /** + * 这里区别于原方法 原方法是改变node节点顺序后发送console.Node.EventType.SIBLING_ORDER_CHANGED通知 这里不需要修改节点顺序 + * 这里发送一个自定义事件 模拟 SIBLING_ORDER_CHANGED 通知 + */ + this.node.emit(UIChangeBrotherEvnet); + } + } + onLoad() { + this.initlized(); + } + /** 初始化 */ + private initlized() { + if (this._isinited) { return; } + this.node.anchorX = 0.5; // 固定content的锚点为中心 + this.node.anchorY = 0.5; + this.node.setContentSize(this.viewSize); // 将content的尺寸设置与view相同 (功能用于空列表时也可以下拉刷新和加载) + // 重写 this.node.getContentSize 方法 因为content的真实尺寸不会随着item的数量变化 + this.node.getContentSize = this.getContentSize.bind(this); + this.node.setPosition(console.Vec2.ZERO); + this.column = this.column < 1 ? 1 : this.column; // 一组item的数量 最少是1 也就是普通的水平/垂直 大于1就是Grid模式 + // 监听content位置变化 刷新header footer节点的相对位置 + this.node.on(console.Node.EventType.POSITION_CHANGED, this.onChangePosition, this); + this.scrollView.view.on(console.Node.EventType.SIZE_CHANGED, this.resetItemSize, this); + this._isinited = true; + } + onDestroy() { + this.node.off(console.Node.EventType.POSITION_CHANGED, this.onChangePosition, this); + this.scrollView.view.off(console.Node.EventType.SIZE_CHANGED, this.resetItemSize, this); + } + private onChangePosition() { + let flag = this.isScrollToFooter; // this.isScrollToFooter = true 向下滑动 false 向上滑动 + if (this.headerToFooter) { + flag ? this.footerToHeaderWatchChilds(flag) : this.headerToFooterWatchChilds(flag); // 倒序刷新 + } else { + flag ? this.headerToFooterWatchChilds(flag) : this.footerToHeaderWatchChilds(flag); // 正序刷新 + } + // 当item 由多到少 并且 当content的位置被重置到初始状态时 重新设置头部的item归位 + if (this.vertical && 0 == this.node.y || this.horizontal && 0 == this.node.x) { + this.header.setPosition(this.getGroupHeader(this.header)); + } + } + public resetItemSize() { + // 重新设置原始尺寸 + for (let i = 0; i < this.children.length; i++) { + this.children[i]["saveOriginSize"](); + } + // 改变头部位置 + let pos = this.getGroupHeader(this.header); + if (this.vertical) { + this.header.x = pos.x; + } else { + this.header.y = pos.y; + } + // 通知改变坐标事件 + for (let i = 0; i < this.children.length; i++) { + this.children[i].emit(console.Node.EventType.POSITION_CHANGED); + } + } + /** 获取缩放宽度 */ + private getScaleWidth(node: console.Node): number { + return node.width * this.getUsedScaleValue(node.scaleX); + } + /** 获取缩放高度 */ + private getScaleHeight(node: console.Node): number { + return node.height * this.getUsedScaleValue(node.scaleY); + } + /** 简单的浅拷贝 */ + private getTempChildren() { + let list = []; + for (let i = 0; i < this._children.length; i++) { + const child = this._children[i]; + list.push(child); + } + return list; + } + /** 正序更新item */ + private headerToFooterWatchChilds(flag) { + let children = this.getTempChildren(); + for (let i = 0; i < children.length; i++) { + const child = children[i]; + child["watchSelf"](flag); + } + } + /** 倒序更新item */ + private footerToHeaderWatchChilds(flag) { + let children = this.getTempChildren(); + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + child["watchSelf"](flag); + } + } + /** 当数据增加、减少时 获取数据偏移 */ + private getDataOffset(value: number) { + // 返回删除数据偏移 (比如当前最大数据值=10,新数据=9 返回-1) + if (this.footer && this.footer["index"] + 1 >= value) { + let offset = this.footer["index"] + 1 - value; + return offset == 0 ? 0 : -offset; + } + // 返回增加数据偏移 + if (this._maxItemTotal == 0 || value < this._maxItemTotal || this._maxItemTotal < this._maxPrefabTotal) { return 0; } // 比如当前最多允许创建10个item 当前显示5个 返回0 + if (this.isGroupFooter(this.footer)) { return 0; } // Grid模式 如果尾部的位置是在一组item中末尾的位置时 返回 0 + return value - this._maxItemTotal; + } + /** + * 当数据增加、减少时 获取节点偏移量 + * 当前数据是这样的 增加1个 增加2个 + * 0,1,2,3 1,2,3 2,3 + * 4,5,6 4,5,6,7 4,5,6,7 + * 8 + */ + private getReallyOffset(dataOffset: number) { + if (!this.header) { return 0; } + if (dataOffset > 0) { // 代表增加item 表格模式下 通过偏移头部来让下方填满 填满后停止偏移 + for (let i = 0; i < dataOffset; i++) { + if (this.isGroupFooter(this.footer)) { return i; } // 返回真实的偏移量 + // 此时如果header 已经是一组item中最后一个时 向下位移 并 设置到一组item的起始位置 + let pos = this.header.getPosition(); + if (this.vertical) { // 垂直滑动时 + if (this.isGroupFooter(this.header)) { // 当列表中第一个item正在一组item中末尾位置时 + if (this.headerToFooter) { + pos.y = this.getGroupBottomY(this.header, this.header); // 正序排列时 Y轴向下偏移(垂直排列时 一组item 头在左尾在右) + } else { + pos.y = this.getGroupTopY(this.header, this.header); // 倒序排列时 Y轴向上偏移(垂直排列时 一组item 头在左尾在右) + } + pos.x = this.getGroupHeader(this.header).x; // X轴向头部偏移 + } else { // 第一个item没有在一组item中末尾的位置 只将第一个item向右偏移 (只偏移X轴) + pos.x = this.getGroupRightX(this.header, this.header); // X轴向右偏移 + } + } else { // 水平滑动时 + if (this.isGroupFooter(this.header)) { // 当列表中第一个item正在一组item中末尾位置时 + if (this.headerToFooter) { + pos.x = this.getGroupRightX(this.header, this.header); // 正序排列时 X轴向右偏移(水平排列时 一组item 头在上尾在下) + } else { + pos.x = this.getGroupLeftX(this.header, this.header); // 倒序排列时 X轴向左偏移(水平排列时 一组item 头在上尾在下) + } + pos.y = this.getGroupHeader(this.header).y; // Y轴向头部偏移 + } else { // 第一个item没有在一组item中末尾的位置 只将第一个item向下偏移 (只偏移Y轴) + pos.y = this.getGroupBottomY(this.header, this.header); // Y轴向下偏移 + } + } + this.header.setPosition(pos); + } + return dataOffset; + } + // 代表减少了item 计算偏移量 offset<0 【注意!这里的逻辑和上面正好相反】 + for (let i = 0; i < Math.abs(dataOffset); i++) { + let pos = console.Vec2.ZERO; + if (this.vertical) { + if (this.isGroupHeader(this.header)) { + pos.x = this.getGroupFooter(this.header).x; + if (this.headerToFooter) { + pos.y = this.getGroupTopY(this.header, this.header); + } else { + pos.y = this.getGroupBottomY(this.header, this.header); + } + } else { + pos.x = this.getGroupLeftX(this.header, this.header); + pos.y = this.header.y; + } + } else { + if (this.isGroupHeader(this.header)) { + pos.y = this.getGroupFooter(this.header).y; + if (this.headerToFooter) { + pos.x = this.getGroupLeftX(this.header, this.header); + } else { + pos.x = this.getGroupRightX(this.header, this.header); + } + } else { + pos.y = this.getGroupTopY(this.header, this.header); + pos.x = this.header.x; + } + } + this.header.setPosition(pos); + } + this.scrollView.calculateBoundary(); + return dataOffset; + } + /** 刷新所有item数据 根据当前item的 index 刷新 */ + private refreshItems(value: number, offset: number = 0) { + if (!this.header) { return; } + let startIndex = this.header["index"] - 1 + offset; // 获取头部item持有的index 加上 数据偏移来计算起始index + for (let i = 0; i < this._children.length; i++) { + const child = this._children[i]; + startIndex++; + // 这里的判断用于无限循环滚动的逻辑 如果索引大于数据总数 索引归零 + if (startIndex > value - 1) { + startIndex = 0; + } else if (startIndex < 0) { // 索引小于0 索引定位到数据尾部 保持首尾相连 + startIndex = value - 1; + } + child["index"] = startIndex; // 设置当前索引 + this.notifyRefreshItem(child); + } + } + /** 从头部到尾部重置数据 */ + private resetToHeader() { + for (let i = 0; i < this._children.length; i++) { + const child = this._children[i]; + child["index"] = i; + this.notifyRefreshItem(child); + } + if (!this.headerLoop && !this.footerLoop) { + this.header?.setPosition(this.getGroupHeader(this.header)); + } else if (!this.scrollToHeaderOrFooter) { + this.header?.setPosition(this.getGroupHeader(this.header)); + } + } + /** 从尾部到头部重置数据 */ + private resetToFooter() { + let index = this._maxItemTotal; + for (let i = this._children.length - 1; i >= 0; i--) { + var child = this._children[i]; + child["index"] = --index; + this.notifyRefreshItem(child); + } + } + /** 删除多余的item */ + private removeChilds(value: number) { + // 有多余的item 需要删除 + let length = this.node.childrenCount - value; + // 删除掉多余的item + for (let i = 0; i < length; i++) { + var child = this.footer; + this.remChild(child); + child.destroy(); + this.node.removeChild(child); + } + if (!this.header) { return; } + // 将头部节点的位置重置到一组item的第一个位置 + let pos = this.getGroupHeader(this.header); + if (this.vertical) { + this.header.x = pos.x; + } else { + this.header.y = pos.y; + } + } + /** 分帧创建item */ + private async asyncCreateItem(...iniData: any[]) { + let self = this; + let data: any[] = iniData[0]; + this._gener?.return("");// 取消上一次的分帧任务(如果任务正在执行) + // 有多余的item 需要删除 不处理 + if (this.node.childrenCount > data[0]) { return this.removeChilds(data[0]); } + // 已经固定item总数 不处理 + if (this._maxPrefabTotal > 0 && this._maxPrefabTotal == this.node.childrenCount) { return; } + // 开始分帧创建item + let total = data[0] - this.node.childrenCount; // 计算当前应该创建的总数 + this._gener = this.getGeneratorLength(total, () => { + // 获取或添加 UISuperItem + // let script = UIPanel.CreateUI(this.prefab, this.node); + // let child = script.node; + // CoroutineV2.Single(script.Show()).Start(); + // child["index"] = this.node.childrenCount - 1; + let child = console.instantiate(self.prefab); + let script = child.getComponent(data[1]); + child["index"] = self.node.childrenCount; + self.addChild(child); + // let item = UIPanel.CreateUI(this.prefab, this.node, data[2]); + // let child = item.node; + let spuerItem = child.getComponent(UISpuerItem) || child.addComponent(UISpuerItem); + self.node.addChild(child); + spuerItem.Init(self, script); + // item在首次创建时立即刷新 避免显示item初始状态 + self.notifyRefreshItem(child); + // 如果创建的是第一个item 设置他的起始位置 之后的item会自动相对于他来设置自己 我们只需要确定第一个位置就行了 + if (self.node.childrenCount == 1) { + let pos = self.getGroupHeader(self.header); // 获取一组item中头部位置 + self.header.setPosition(pos); + /** + * 利用console.ScrollView的方法来设置content的起始位置 由于content在初始化的时候固定了锚点都为0.5 所以这里必然是坐标0 + * 如果你没有其他需求确定用0.5锚点的话 这里可以自己设置为console.Vec2.ZERO 节省不必要的计算(实际上计算量可忽略不计) + */ + self.scrollView.calculateBoundary(); + } + let selfHorW, viewHorW; + if (self.vertical) { + selfHorW = self.getReallySize().height; + viewHorW = self.viewSize.height; + } else { + selfHorW = self.getReallySize().width; + viewHorW = self.viewSize.width; + } + /** + * 根据排列方向 来判断对比宽度还是高度 + * 这里使用参数this.multiple来判断是否需要继续创建 默认为2倍 比如view可视尺寸为800 2倍就是1600 + * 根据之前所创建的所有item的尺寸计算是否满足这个尺寸 如果满足则不再继续创建 + * 由于是分帧加载 所以下一次创建会等这一次的返回结果 返回false 则终止分帧任务 + */ + if (selfHorW >= viewHorW * self.multiple && self.isGroupFooter(self.footer)) { + self._maxPrefabTotal = self.node.childrenCount; // 固定item数量 不在继续创建 + return false; + } + return true; + }); + await this.exeGenerator(this._gener, 10); // 执行分帧任务 1帧创建10个 + } + /** 同步添加本地变量 children 并发送 UIChangeBrotherEvnet 通知*/ + private addChild(node: console.Node) { + this._children.push(node); + this.node.emit(UIChangeBrotherEvnet); + } + /** 同步移除本地变量 children 并发送 UIChangeBrotherEvnet 通知 */ + private remChild(node: console.Node) { + let index = this._children.indexOf(node); + if (index == -1) { return; } + this._children.splice(index, 1); + this.node.emit(UIChangeBrotherEvnet); + } + /** 分帧加载 */ + private * getGeneratorLength(length: number, callback: Function, ...params: any): Generator { + for (let i = 0; i < length; i++) { + let result = callback(i, ...params); + if (result) { + yield; + } else { + return; + } + } + } + /** 分帧执行 */ + private exeGenerator(generator: Generator, duration: number) { + return new Promise((resolve, reject) => { + let gen = generator; + let execute = () => { + let startTime = new Date().getTime(); + for (let iter = gen.next(); ; iter = gen.next()) { + if (iter == null || iter.done) { + resolve(null); + return; + } + if (new Date().getTime() - startTime > duration) { + setTimeout(() => execute(), console.director.getDeltaTime() * 1000); + return; + } + } + }; + execute(); + }); + } +} diff --git a/src/script/Engine/Utils/ScrollView/UISuperLayout.ts.meta b/src/script/Engine/Utils/ScrollView/UISuperLayout.ts.meta new file mode 100644 index 0000000..821baf9 --- /dev/null +++ b/src/script/Engine/Utils/ScrollView/UISuperLayout.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "67f1a0e4-877e-4ad0-bc1b-e1175c620ca1", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/Utils/ScrollView/UISuperScrollView.ts b/src/script/Engine/Utils/ScrollView/UISuperScrollView.ts new file mode 100644 index 0000000..566f836 --- /dev/null +++ b/src/script/Engine/Utils/ScrollView/UISuperScrollView.ts @@ -0,0 +1,284 @@ +/* + * @Author: steveJobs + * @Email: icipiqkm@gmail.com + * @Date: 2020-11-19 01:15:04 + * @Last Modified by: steveJobs + * @Last Modified time: 2020-12-04 14:35:43 + * @Description: Description + */ +import UISuperLayout from "./UISuperLayout"; +const { ccclass, property, menu } = console._decorator; +const EPSILON = 1e-4; +export interface UISuperHeaderAndFooterEvent { + /** 执行动作 true:满足触发条件 */ + action: boolean; + /** 根据参数headerOutOffset或footerOutOffset 来计算的进度值 */ + progress: number; + /** 当前进度状态 + * touch=触摸中 正在触摸滑动中 + * wait=等待中 已经满足了触发的更新动作的条件 + * lock=锁定中 当前正在执行刷新或加载 + * release=释放中 + */ + progressStage: "touch" | "wait" | "lock" | "release"; +} +@ccclass +@menu("Plug-in/ScrollView/UISpuerScrollView") +export default class UISpuerScrollView extends console.ScrollView { + @property({ + displayName: "顶部偏移量", + tooltip: "下拉时超过此偏移会发送下拉事件" + }) headerOutOffset: number = 200; + @property({ displayName: "满足触发Header的倍数" }) headerMultiple: number = 2; + @property({ + displayName: "底部偏移量", + tooltip: "上拉时超过此偏移会发送上拉事件" + }) footerOutOffset: number = 200; + @property({ displayName: "满足触发Footer的倍数" }) footerMultiple: number = 2; + @property({ + type: console.Component.EventHandler, + displayName: "下拉事件" + }) pullDownEvents: console.Component.EventHandler[] = []; + @property({ + type: console.Component.EventHandler, + displayName: "上拉事件" + }) pullUpEvents: console.Component.EventHandler[] = []; + public get view(): console.Node { return this["_view"]; } + public set autoScrolling(value: boolean) { this["_autoScrolling"] = value; } + public get autoScrolling() { return this["_autoScrolling"]; } + private isMoveHeader: boolean = false; + private isMoveFooter: boolean = false; + private isLockHeader: boolean = false; + private isLockFooter: boolean = false; + private headerProgress: number = 0; + private footerProgress: number = 0; + private _layout: UISuperLayout = null; + private get layout(): UISuperLayout { + if (this._layout == null) { this._layout = this.content.getComponent(UISuperLayout) } + return this._layout; + } + /** 当前头部的item是否真的是数据的开头 也就是0 */ + private get isHeader() { + if (this.layout.headerToFooter) { + if (this.layout?.header) { + return this.layout?.header["index"] == 0; + } + } else { + if (this.layout?.footer) { + return this.layout?.footer["index"] == this.layout.maxItemTotal - 1; + } + } + return true; + } + /** 当前尾部的item是否真的是数据的结尾 */ + private get isFooter() { + if (this.layout.headerToFooter) { + if (this.layout?.footer) { + return this.layout.footer["index"] == this.layout.maxItemTotal - 1; + } + } else { + if (this.layout?.header) { + return this.layout?.header["index"] == 0; + } + } + return true; + } + /** 是否需要计算?如果上拉/下拉事件没有监听者则不需要相关的计算 */ + public get isCalculPull() { + return this.pullDownEvents.length > 0 || this.pullUpEvents.length > 0; + } + public calculateBoundary() { + this["_calculateBoundary"](); + + } + public getHowMuchOutOfBoundary(offset?: console.Vec2) { + return this["_getHowMuchOutOfBoundary"](offset); + } + onLoad() { + this.node.on(console.Node.EventType.SIZE_CHANGED, this.onChangeSize, this); + } + onDestroy() { + this.node.off(console.Node.EventType.SIZE_CHANGED, this.onChangeSize, this); + } + private onChangeSize() { + let widget = this.view.getComponent(console.Widget); + if (!widget) { return } + widget.updateAlignment(); + } + /** 释放 功能用于上拉加载下拉刷新 解锁头尾固定的尺寸 */ + public release() { + this.isMoveHeader = false; + this.isMoveFooter = false; + if (this.isLockHeader || this.isLockFooter) { + let outOfBoundary = this.getHowMuchOutOfBoundary(); + let offset = this.vertical ? outOfBoundary.y : -outOfBoundary.x; + let autoScroll = true; + if (offset == 0 || this.isLockHeader && offset < 0 || this.isLockFooter && offset > 0) { + this.clearProgress(); + autoScroll = false; + } + this.isLockHeader = false; + this.isLockFooter = false; + if (autoScroll) { + this["_outOfBoundaryAmountDirty"] = true; + this["_processInertiaScroll"](); + } + } else { + this.clearProgress(); + } + } + + /**重置列表 当列表滑动到底部时 然后不管通过什么方式(同步|异步)减少了整体的(高度|缩放|尺寸) 时保证内容显示正确 */ + public reset() { + this["_outOfBoundaryAmountDirty"] = true; + let offset = this.getHowMuchOutOfBoundary(); + if (!offset.fuzzyEquals(console.v2(0, 0), EPSILON)) { + this["_processInertiaScroll"](); + } + } + private _onTouchMoved(event: console.Event.EventTouch, captureListeners) { + super["_onTouchMoved"](event, captureListeners); + if (this.isCalculPull) { + let outOfBoundary = this.getHowMuchOutOfBoundary(); + let offset = this.vertical ? outOfBoundary.y : -outOfBoundary.x; + if (offset > 0 && this.isHeader && !this.isLockHeader && !this.isLockFooter) { + this.headerProgress = offset < EPSILON ? 0 : offset / this.headerOutOffset; + this.isMoveHeader = this.headerProgress >= this.headerMultiple; + this.emitPullDownEvent({ action: false, progress: this.headerProgress, progressStage: this.isMoveHeader ? "wait" : "touch" }); + this.emitPullUpEvent({ action: false, progress: 0, progressStage: "release" }); + } else if (offset < 0 && this.isFooter && !this.isLockFooter && !this.isLockHeader) { + this.footerProgress = -offset < EPSILON ? 0 : -offset / this.footerOutOffset; + this.isMoveFooter = this.footerProgress >= this.footerMultiple; + this.emitPullUpEvent({ action: false, progress: this.footerProgress, progressStage: this.isMoveFooter ? "wait" : "touch" }); + this.emitPullDownEvent({ action: false, progress: 0, progressStage: "release" }); + } + } + } + private _dispatchEvent(event) { + super["_dispatchEvent"](event); + if (event == "scroll-ended") { + this.layout.scrollToHeaderOrFooter = false; // 功能用于控制循环滚动时使用scrollTo方法滚动带来的效果问题 + } + } + private _getContentTopBoundary() { + let viewSize = this.view.getContentSize(); + let local = 0; + if (this.layout?.header && this.layout.getReallySize().height > viewSize.height) { + local = this.layout.topBoundary; // 返回头部item上边距 + } else { + // 功能用于无内容/少量内容时也可以上拉加载下拉刷新 如果所有item加起来的尺寸不足以撑满整个可视区域时 直接使用view可视尺寸 + local = this._getContentBottomBoundary() + viewSize.height; + } + if (this.isHeader && this.isLockHeader) { + local += this.headerOutOffset; // 功能用于上拉加载 下拉刷新 让整个content多一个 headerOutOffset 的尺寸 + } + return local; + } + private _getContentBottomBoundary() { + let viewSize = this.view.getContentSize(); + let local = 0; + if (this.layout?.footer && this.layout.getReallySize().height > viewSize.height) { + local = this.layout.bottomBoundary; // 返回尾部item上边距 + } else { + // 功能用于无内容/少量内容时也可以上拉加载下拉刷新 如果所有item加起来的尺寸不足以撑满整个可视区域时 直接使用view可视尺寸 + local = this.layout.node.y - this.layout.node.getAnchorPoint().y * viewSize.height; + } + if (this.isFooter && this.isLockFooter) { + local -= this.footerOutOffset; // 功能用于上拉加载 下拉刷新 让整个content多一个 footerOutOffset 的尺寸 + } + return local; + } + private _getContentLeftBoundary() { + let viewSize = this.view.getContentSize(); + let local = 0; + if (this.layout?.header && this.layout.getReallySize().width > viewSize.width) { + local = this.layout.leftBoundary; // 返回头部item左边距 + } else { + // 功能用于无内容/少量内容时也可以上拉加载下拉刷新 如果所有item加起来的尺寸不足以撑满整个可视区域时 直接使用view可视尺寸 + local = this.layout.node.x - this.layout.node.getAnchorPoint().x * viewSize.width; + } + if (this.isHeader && this.isLockHeader) { + local -= this.headerOutOffset; // 功能用于上拉加载 下拉刷新 让整个content多一个 headerOutOffset 的尺寸 + } + return local; + } + private _getContentRightBoundary() { + let viewSize = this.view.getContentSize(); + let local = 0; + if (this.layout?.footer && this.layout.getReallySize().width > viewSize.width) { + local = this.layout.rightBoundary; // 返回头部item右边距 + } else { + // 功能用于无内容/少量内容时也可以上拉加载下拉刷新 如果所有item加起来的尺寸不足以撑满整个可视区域时 直接使用view可视尺寸 + local = this._getContentLeftBoundary() + viewSize.width; + } + if (this.isFooter && this.isLockFooter) { + local += this.footerOutOffset; // 功能用于上拉加载 下拉刷新 让整个content多一个 footerOutOffset 的尺寸 + } + return local; + } + private _startAutoScroll(deltaMove, timeInSecond, attenuated) { + if (this.isCalculPull) { // 如果没有刷新/加载的监听者 则不计算 + if (this.isMoveHeader && !this.isLockHeader) { // 锁住头部 意思就是已经触发了下拉事件 应用层应该做些刷新的动作 + this.isLockHeader = true; + this.vertical && (deltaMove.y -= this.headerOutOffset); + this.horizontal && (deltaMove.x += this.headerOutOffset); + this.emitPullDownEvent({ action: true, progress: this.headerProgress, progressStage: "lock" }); + } else if (this.isMoveFooter && !this.isLockFooter) { // 锁住尾部 意思就是已经触发了上拉事件 应用层应该做些加载的动作 + this.isLockFooter = true; + this.vertical && (deltaMove.y += this.footerOutOffset); + this.horizontal && (deltaMove.x -= this.footerOutOffset); + this.emitPullUpEvent({ action: true, progress: this.footerProgress, progressStage: "lock" }); + } + } + super["_startAutoScroll"](deltaMove, timeInSecond, attenuated); + } + private _updateScrollBar(outOfBoundary) { + super["_updateScrollBar"](outOfBoundary); + if (!this.isCalculPull) { return } // 如果没有刷新/加载的监听者 则不计算 + if (this["_autoScrollBraking"]) { return } // 自动回弹时不计算 (非手动) + if (!this.autoScrolling) { return } // 非自动滚动时不计算 + let offset = this.vertical ? outOfBoundary.y : -outOfBoundary.x; + if (offset > 0) { // 下滑 + let progress = offset < EPSILON ? 0 : offset / this.headerOutOffset; // 根据参数 headerOutOffset 计算当前下滑的办百分比 + let progressStage; + if (this.isLockHeader) { + this.headerProgress = this.headerProgress == 1 ? this.headerProgress : Math.max(progress, 1); + progressStage = "lock" // 锁定状态 + } else { + this.headerProgress = progress < this.headerProgress ? progress : this.headerProgress; + progressStage = "release" // 释放状态 + } + this.emitPullDownEvent({ action: false, progress: this.headerProgress, progressStage: progressStage }); + + } else if (offset < 0) { // 上拉 + let progress = -offset < EPSILON ? 0 : -offset / this.footerOutOffset; // 根据参数 footerOutOffset 计算当前下滑的办百分比 + let progressStage; + if (this.isLockFooter) { + this.footerProgress = this.footerProgress == 1 ? this.footerProgress : Math.max(progress, 1); + progressStage = "lock" // 锁定状态 + } else { + this.footerProgress = progress < this.footerProgress ? progress : this.footerProgress; + progressStage = "release" // 释放状态 + } + this.emitPullUpEvent({ action: false, progress: this.footerProgress, progressStage: progressStage }); + + } else if (offset == 0) { + // 正常滑动时 如果没有锁定头和尾时 释放所有进度 + if (!this.isLockHeader && !this.isLockFooter) { + this.clearProgress(); + } + } + } + private clearProgress() { + this.headerProgress = 0; + this.footerProgress = 0; + this.emitPullDownEvent({ action: false, progress: 0, progressStage: "release" }); + this.emitPullUpEvent({ action: false, progress: 0, progressStage: "release" }); + } + private emitPullDownEvent(data: UISuperHeaderAndFooterEvent) { + console.Component.EventHandler.emitEvents(this.pullDownEvents, this, data); + } + private emitPullUpEvent(data: UISuperHeaderAndFooterEvent) { + console.Component.EventHandler.emitEvents(this.pullUpEvents, this, data); + } +} diff --git a/src/script/Engine/Utils/ScrollView/UISuperScrollView.ts.meta b/src/script/Engine/Utils/ScrollView/UISuperScrollView.ts.meta new file mode 100644 index 0000000..52edee1 --- /dev/null +++ b/src/script/Engine/Utils/ScrollView/UISuperScrollView.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.8", + "uuid": "dfb04646-c016-4594-b7b3-8d83fa7a925a", + "isPlugin": false, + "loadPluginInWeb": true, + "loadPluginInNative": true, + "loadPluginInEditor": false, + "subMetas": {} +} \ No newline at end of file diff --git a/src/script/Engine/catan.d.ts b/src/script/Engine/catan.d.ts new file mode 100644 index 0000000..c299267 --- /dev/null +++ b/src/script/Engine/catan.d.ts @@ -0,0 +1 @@ +declare var require: (id: string) => any; \ No newline at end of file diff --git a/src/script/Tools.ts b/src/script/Tools.ts new file mode 100644 index 0000000..0a94a8c --- /dev/null +++ b/src/script/Tools.ts @@ -0,0 +1,11 @@ + +export class Tools { + + //#region Custom + + public static Sleep(ms: any): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + //#endregion +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..35c93f9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "esnext", + "useDefineForClassFields": true, + "module": "esnext", + "moduleResolution": "node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": false, + "esModuleInterop": true, + "lib": [ + "esnext", + "dom" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue" + ], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] +} \ No newline at end of file diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..e993792 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "composite": true, + "module": "esnext", + "moduleResolution": "node" + }, + "include": ["vite.config.ts"] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..fc2f369 --- /dev/null +++ b/tslint.json @@ -0,0 +1,116 @@ +{ + "defaultSeverity": "warning", + "rules": { + "ban": [ + true, + [ + "_", + "extend" + ], + [ + "_", + "isNull" + ], + [ + "_", + "isDefined" + ] + ], + "class-name": false, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "eofline": false, + "forin": false, + "indent": [ + true, + 4 + ], + "interface-name": [ + true, + "never-prefix" + ], + "jsdoc-format": true, + "label-position": true, + "label-undefined": true, + "max-line-length": [ + false, + 140 + ], + "no-arg": true, + "no-bitwise": false, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": true, + // "no-eval": true, + "no-string-literal": false, + "no-trailing-comma": true, + "no-trailing-whitespace": true, + "no-unused-expression": false, + "no-unused-variable": true, + "no-unreachable": true, + "no-use-before-declare": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": [ + true, + "double" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef": [ + true, + "call-signature", + "parameter", + "property-declaration", + "variable-declaration" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace" + }, + { + "index-signature": "space" + } + ], + "use-strict": [ + true, + "check-module", + "check-function" + ], + "variable-name": false, + "whitespace": [ + false, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..ad61010 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,8 @@ +import vue from '@vitejs/plugin-vue' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + base: "./", + plugins: [vue()] +})