commit 68c8939d60d5547f0a4b32f68831f2a3c0cffbaf Author: thepaperpilot Date: Mon Sep 26 18:41:10 2022 -0500 Fix isFunction typing diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..2a1d0bc --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,28 @@ +require("@rushstack/eslint-patch/modern-module-resolution"); + +module.exports = { + root: true, + env: { + node: true + }, + extends: [ + "plugin:vue/vue3-essential", + "@vue/eslint-config-typescript/recommended", + "@vue/eslint-config-prettier" + ], + parserOptions: { + ecmaVersion: 2020 + }, + ignorePatterns: ["src/lib"], + rules: { + "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", + "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", + "vue/script-setup-uses-vars": "warn", + "vue/no-mutating-props": "off", + "vue/multi-word-component-names": "off" + }, + globals: { + defineProps: "readonly", + defineEmits: "readonly" + } +}; diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..d6cb68c --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,23 @@ +name: Build and Deploy +on: + push: + branches: + - 'main' +jobs: + build-and-deploy: + if: github.repository != 'profectus-engine/Profectus' # Don't build placeholder mod on main repo + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v2 + + - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built. + run: | + npm ci + npm run build + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@v4.2.5 + with: + branch: gh-pages # The branch the action should deploy to. + folder: dist # The folder the action should deploy. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..5a2d131 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,19 @@ +name: Build and Deploy +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + - run: npm ci + - run: npm run build --if-present + - run: npm test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..403adbc --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules +/dist + + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..008a2f9 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "arrowParens": "avoid", + "endOfLine": "auto", + "printWidth": 100, + "tabWidth": 4, + "trailingComma": "none" +} diff --git a/.replit b/.replit new file mode 100644 index 0000000..89785c6 --- /dev/null +++ b/.replit @@ -0,0 +1,13 @@ +run = "npm install; npm run dev" + +[packager] +language = "nodejs" + [packager.features] + packageSearch = true + guessImports = false + +[languages.javascript] +pattern = "**/{*.js,*.jsx,*.ts,*.tsx}" + + [languages.javascript.languageServer] + start = [ "typescript-language-server", "--stdio" ] diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..28c8581 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-node", + "request": "launch", + "name": "Debug Current Test File", + "autoAttachChildProcesses": true, + "skipFiles": [ + "/**", + "**/node_modules/**" + ], + "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs", + "args": [ + "run", + "${relativeFile}" + ], + "smartStep": true, + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..77377bd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "vitest.commandLine": "npx vitest" +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b982041 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,322 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.5.2] - 2022-08-22 +### Added +- onLoad event +- fontsLoaded event +- Dismissable notification you can add to VueFeatures when they're interactable +- Option on exponential modifiers to better support numbers less than 1 +- Utility function to track if a VueFeature is being hovered over +- Utility to unwrap Resources that may be in refs +- Utility to join JSX elements together with a joiner +- Type for converting readonly string arrays into a union of string values +### Changed +- The main and prestige layers no longer use arrow functions for their options functions +- Modifiers are now lazily loaded +- Collapsible modifier sections are now lazily loaded +- Converted several refs into shallow refs for improved performance +- Roboto Mono and Material Icons fonts are now bundled instead of downloaded from the web, so they work with PWAs +- Node bounds are now updated whenever that context has a node removed or added, fixing many issues with incorrect bounds +### Fixed +- trackResetTime not updating +- colorText prepending $s +- Default .replit config was broken +- Pixi.js canvases no longer rendering +- Node positions being shifted on initial page load due to fonts loading on firefox +- Modifier sections looked wrong if the topmost section wasn't visible + +## [0.5.1] - 2022-07-17 +### Added +- Notif component that displays a jumping exclamation point +- showAmount boolean to buyable displays +- Tab families now take option to style the tab buttons container +- Utility for creating text of a certain color +### Changed +- Improved typing of player.layers +- Improved typing of createCollapsibleModifierSections's parameters +- Made Particles vue component typed as GenericComponent due to issues generating documentation +- Minimized how much of pixi.js is included in the built site +- Split bundles into smaller bundles for faster loading +- Updated TypeScript +- Descriptions on buyables are now optional +- Improved tooltips performance +- Improved how MainDisplay displays effect strings +- MainDisplays are now sticky +- processComputable now binds uncached functions as well +### Fixed +- trackResetTime stopped working once its layer was removed and re-added +- Runtime compilation was disabled in vite config +- Websites had to be hosted on root directory to have assets load correctly +- Tooltips' persistent ref was lazily created +- In some situations Links would not update its bounding rect +- Achievements' and milestones' onComplete callbacks were firing on load +- Processed JSXFunctions were not considered coercable components by isCoercableComponent +- Error from passing in overlay text to bar component +### Removed +- lodash.cloneDeep dependency, which hasn't been used in awhile +- Some unused configs from vue-cli-service +### Documented +- Update vitepress, and updated the content of many pages +- Rest of /game +- Rest of /data +- layers.tsx +- Any type augmentations to Window object +- Various cleanup of docs comments +- Fixed doc generation being broken from switch to vite +### Tests +- Switched from jest to vitest + +## [0.5.0] - 2022-06-27 +### Added +- Projects now cache for offline play, and show notification when an update is available +- Projects can now be "installed" as a Progressive Web App +- Conversions can now be given a custom spend function, which defaults to setting the base resource amount to 0 +- Components for displaying Floor and Square Root symbols +### Changed +- **BREAKING** Several projInfo properties now default to empty strings, to prevent things like reusing project IDs +- **BREAKING** Replaced vue-cli-service with vite (should not break most projects) +- Updated dependencies +- Made all type-only imports explicit +- setupPassiveGeneration now works properly on independent conversions +- setupPassiveGeneration now takes an option cap it can't go over +- Improved typing for PlayerData.layers +- Options Functions have an improved `this` type - it now includes the options themselves +- Removed v-show being used in data/common.tsx +### Tests +- Implement Jest, and running tests automatically on push +- Tests written for utils/common.ts + +## [0.4.2] - 2022-05-23 +### Added +- costModifier to conversions +- onConvert(amountGained) to conversions +### Changed +- **BREAKING** getFirstFeature has a new signature, that will lead to improved performance +- trackResetTime is now intended to be used with a reset button +- regularFormat handles small numbers better +- Slider tooltips now appear below the slider, not above +- Node's mutation observers now ignore attributes. This shouldn't have issues with links/particle effect positions, but prevents a _lot_ of unnecessary node updates +- OptionsFunc no longer takes its S type parameter, as it was unnecessary. Layer options functions now have proper `this` typing + - Several functions have been updated to take BaseLayer instead of GenericLayer, to allow them to work with `this` inside layer options functions +### Fixed +- Particle effects and links would not always appear on reload or when switching layers +- Particle effects and links no longer appear in wrong spot after nodes are added or removed +- Collapsibles having wrong widths on the button and collapsed content sections +- Additive modifiers with negative values appeared like "+-" instead of "-" +- Buyables' onPurchase was not being called +- Reset button would display "Next:" if the buyMax property is a ref + +## [0.4.1] - 2022-05-10 +### Added +- findFeatures can now accept multiple feature types +- excludeFeatures can now be used to find features with a feature type _blacklist_ +- All the icons in the saves manager now have tooltips +### Changed +- All touch events that can be passive now are +- Layers' style and classes attributes are now applied to the tab element rather than the layer-tab +- Saving now always uses lz-string, and saveEncoding has been renamed to exportEncoding + - The property will now only affect exports, and defaults to base64 so exports can be shared in more places without issues +- Buyables can now have their onClick/purchase function overwritten +### Fixed +- Arrays in player were not being wrapped in proxies for things like NaN detection +- Error when switching between saves with different layers +- Links would sometimes error from trying to use nodes that were removed earlier that frame +- createModifierSection would require modifiers to have revert and enabled properties despite not using them +- Tab buttons would not use the style property if it was a ref +- Typings on the Board vue component were incorrect +- Offline time would always show, if offlineLimit is set to 0 +- Buyables will now call onPurchase() when cost and/or resource were not set +- Presets dropdown wouldn't deselect the option after creating the save +### Documented +- feature.ts + +## [0.4.0] - 2022-05-01 +### Added +- Saves can now be encoded in two new options: plaintext and lz compressed, determined by a new "saveEncoding" property in projInfo + - Saves will be loaded in whatever format is detected. The setting only applies when writing saves +- createModifierSection has new parameter to override the label used for the base value +- createCollapsibleModifierSections utility function to display `createModifierSection`s in collapsible forms +### Fixed +- Saves manager would not clear the current save from its cache when switching saves, leading to progress loss if flipping between saves +- Layer.minWidth being ignored +- Separators between tabs (player.tabs) would not extend to the bottom of the screen when scrolling +- Tree nodes not being clicked on their edges +### Changed +- **BREAKING** No features extend persistent anymore + - This will break ALL existing saves that aren't manually dealt with in fixOldSave + - Affected features: Achievement, Buyable, Grid, Infobox, Milestone, TabFamily, and Upgrade + - Affected features will now have a property within them where the persistent ref is stored. This means new persistent refs can now be safely added to these features +- Features with option functions with 0 required properties now don't require passing in an options function +- Improved the look of the goBack and minimize buttons (and made them more consistent with each other) +- Newly created saves are immediately switched to +- TooltipDirection and Direction have been merged into one enum +- Made layers shallow reactive, so it works better with dynamic layers +- Modifier functions all have more explicit types now +- Scaling functions take computables instead of processed computables +### Removed +- Unused tsParticles.d.ts file +### Documented +- modifiers.ts +- conversions.ts + +## [0.3.3] - 2022-04-24 +### Fixed +- Spacing between rows in Tree components +- Computed style attributes on tooltips were ignored +- Tooltips could cause infinite loops due to cyclical dependencies + +## [0.3.2] - 2022-04-23 +### Fixed +- Clickables and several other elements would not register clicks sometimes, if the display is updating rapidly +- createLayerTreeNode wasn't using display option correctly + +## [0.3.1] - 2022-04-23 +### Added +- Render utility methods that always return JSX Elements +### Changed +- **BREAKING** Tooltips overhaul + - Tree Nodes no longer have tooltips related properties + - Tooltips can now be added to any feature with a Vue component using the `addTooltip` function + - Any tooltip can be made pinnable by setting pinnable to true in the addTooltip options, or by passing a `Ref` to a Tooltip component + - Pinned tooltips have an icon to represent that. It can be disabled by setting the theme's `showPin` property to false +- Modifiers are now their own features rather than a part of conversions + - Including utilities to display the current state of all the modifiers +- TabFamilies' options function is now optional +- Layer.minWidth can take string values + - If parseable into a number, it'll have "px" appended. Otherwise it'll be un-processed +- TreeNodes now have Vue components attached to them +- `createResourceTooltip` now shows the resource name +- Made classic and aqua theme's `feature-foreground` color dark rather than light + +## [0.3.0] - 2022-04-10 +### Added +- conversion.currentAt [#4](https://github.com/profectus-engine/Profectus/pull/4) +- OptionsFunc utility type, improving type inferencing in feature types +- minimumGain property to ResetButton, defaulting to 1 +### Changed +- **BREAKING** Major persistence rework + - Removed makePersistent + - Removed old Persistent, and renamed PersistentRef to Persistent + - createLazyProxy now takes optional base object (replacing use cases for makePersistent) + - Added warnings when creating refs outside a layer + - Added warnings when persistent refs aren't included in their layer object +- **BREAKING** createLayer now takes id as the first param, rather than inside the option function +- resetButton now shows "Req:" instead of "Next:" when conversion.buyMax is false +- Conversion nextAt and currentAt now cap at 0 after reverting modifier +### Fixed +- Independent conversion gain calculation [#4](https://github.com/profectus-engine/Profectus/pull/4) +- Persistence issue when loading layer dynamically +- resetButton's gain and requirement display being incorrect when conversion.buyMax is false +- Independent conversions with buyMax false capping incorrectly + +## [0.2.2] - 2022-04-01 +Unironically posting an update on April Fool's Day ;) +### Changed +- **BREAKING** Replaced tsparticles with pixi-emitter. Different options, and behaves differently. +- Print key and value in lazy proxy's setter message +- Update bounding boxes after web fonts load in +### Removed +- safff.txt + +## [0.2.1] - 2022-03-29 +### Changed +- **BREAKING** Reworked conversion.modifyGainAmount into conversion.gainModifier, with several utility functions. This makes nextAt accurate with modified gain +### Fixed +- Made overlay nav not overlap leftmost layer + +## [0.2.0] - 2022-03-27 +### Added +- Particles feature +- Collapsible layout component +- Utility function for splitting off the first from the list of features that meets a given filter +### Changed +- **BREAKING** Reworked most of the code from Links into a generic Context component that manages the positions of features in the DOM +- Updated vue-cli and TS dependencies +- Challenges cannot be started when maxed, and `canStart` now defaults to `true` +- onClick listeners on various features now get passed a MouseEvent or TouchEvent when possible +- Minor style changes to Milestones, most notably removing min-height +### Fixed +- Buyables didn't support CoercableComponents for displays +- TreeNodes would have a double glow effect on hover +### Removed +- Unused mousemove listener attached to App.vue + +## [0.1.4] - 2022-03-13 +### Added +- You can now access this.on() from within a createLayer function (and other BaseLayer properties) +- Support for passing non-persistent refs to createResource +- dontMerge class to allow features to ignore mergeAdjacent +### Fixed +- Clickables would not merge adjacent +- onClick and onHold functions would not be bound to their object when being called +- Refs passed to a components style prop would be ignored +- Fixed z-index issue when stopping hovering over features with .can class + +## [0.1.3] - 2022-03-11 +### Added +- Milestone.complete +- Challenge.complete +- setupAutoClick function to run a clickable's onClick every tick +- setupAutoComplete function to attempt to complete a challenge every tick +- isAnyChallengeActive function to query if any challenge from a given list is active +- Hotkeys now appear in info modal, if any exist +- projInfo.json now includes a "enablePausing" option that can be used to prevent the player from pausing the game +- Added a "gameWon" global event +### Changed +- **BREAKING** Buyables now default to an infinite purchase limit +- **BREAKING** devSpeed, playedTime, offlineTime, and diff now use numbers instead of Decimals +- **BREAKING** Achievements and milestones now use watchEffect to check for completion, instead of polling each tick. shouldEarn properties now only accept functions +- Cached more decimal values for optimization +### Fixed +- Many types not being exported +- setupHoldToClick wouldn't stop clicking after a component is unmounted +- Header's banner would not have correct width +### Removed +- **BREAKING** Removed setupAutoReset +### Documentation +- Support for documentation generation using typedoc +- Hide main layer from docs +- Hide prestige layer from docs +- Use stub declaration files for libs that don't provide types (vue-panzoom and vue-textarea-autosize) + +## [0.1.2] - 2022-03-05 +### Changed +- **BREAKING** Removed "@" path alias, and used baseUrl instead +- **BREAKING** Renamed createExponentialScaling to createPolynomialScaling and removed coefficient parameter +- Changed options passed into createLayerTreeNode; now allows overriding display +- App component is no longer cloned before being passed to `createApp` +- Changed TS version from ^4.5.4 to ~4.5.5 +### Fixed +- Document title is set as soon as possible now + +## [0.1.1] - 2022-03-02 +### Added +- Configuration for Glitch projects +- Configuration for Replit projects +- Hide versionTitle if blank +### Changed +- **BREAKING** Renamed modInfo.json -> projInfo.json +- **BREAKING** Renamed mod.tsx -> projEntry.tsx +- Improved performance of branch drawing code +- Improved performance of formatting numbers +- Changed some projInfo default values to empty strings +- Renamed projInfo.allowSmall -> projInfo.defaultShowSmall +### Fixed +- Spacing on discord logo in NaN screen +- Some files accessing old location for persistence code +- Fixed lint-staged not being listed in devDependencies +- Branch locations were not accurate after scrolling +- Saves Manager displayed "default body" while closing +- Reset buttons activating when held down when canClick is false +- Lifting up on auto clickable elements not stopping the auto clicker +### Removed +- Removed Theme.stackedInfoboxes +- Removed Theme.showSingleTab + +## [0.1.0] - Initial Release diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..01c0262 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Anthony Lawn + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e535eb2 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# Profectus + +A game engine that grows with you + +[![Run on Repl.it](https://repl.it/badge/github/profectus-engine/Profectus)](https://repl.it/github/profectus-engine/Profectus) + +[Read the docs](https://moddingtree.com) + +## Project setup +``` +npm install +``` + +### Hosts dev server and hot-reloads modules as they're changed +``` +npm start +``` + +### Compiles and minifies for production +``` +npm run build +``` + +### Hosts the production build +``` +npm run preview +``` + +### Lints and fixes files +``` +npm run lint +``` + +### Runs the tests using vite-jest +``` +npm run test +``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..9cc3526 --- /dev/null +++ b/index.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + Profectus + + + + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..491a72f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12295 @@ +{ + "name": "profectus", + "version": "0.5.2", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "profectus", + "version": "0.5.2", + "dependencies": { + "@fontsource/material-icons": "^4.5.4", + "@fontsource/roboto-mono": "^4.5.8", + "@pixi/app": "~6.3.2", + "@pixi/core": "~6.3.2", + "@pixi/particle-emitter": "^5.0.4", + "@pixi/ticker": "~6.3.2", + "@vitejs/plugin-vue": "^2.3.3", + "@vitejs/plugin-vue-jsx": "^1.3.10", + "is-plain-object": "^5.0.0", + "lz-string": "^1.4.4", + "nanoevents": "^6.0.2", + "vite": "^2.9.12", + "vite-plugin-pwa": "^0.12.0", + "vite-tsconfig-paths": "^3.5.0", + "vue": "^3.2.26", + "vue-next-select": "^2.10.2", + "vue-panzoom": "^1.1.6", + "vue-textarea-autosize": "^1.1.1", + "vue-toastification": "^2.0.0-rc.1", + "vue-transition-expand": "^0.1.0", + "vuedraggable": "^4.1.0" + }, + "devDependencies": { + "@ivanv/vue-collapse-transition": "^1.0.2", + "@rushstack/eslint-patch": "^1.1.0", + "@types/lz-string": "^1.3.34", + "@vue/eslint-config-prettier": "^7.0.0", + "@vue/eslint-config-typescript": "^10.0.0", + "eslint": "^8.6.0", + "jsdom": "^20.0.0", + "prettier": "^2.5.1", + "typescript": "^4.7.4", + "vitest": "^0.17.1", + "vue-tsc": "^0.38.1" + }, + "engines": { + "node": "16.x" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", + "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", + "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.10", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.10", + "@babel/types": "^7.18.10", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz", + "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==", + "dependencies": { + "@babel/types": "^7.18.10", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", + "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + "dependencies": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.20.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz", + "integrity": "sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz", + "integrity": "sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz", + "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", + "dependencies": { + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", + "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", + "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz", + "integrity": "sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz", + "integrity": "sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w==", + "dependencies": { + "@babel/helper-function-name": "^7.18.9", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.11", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", + "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", + "dependencies": { + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.11.tgz", + "integrity": "sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz", + "integrity": "sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", + "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "dependencies": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", + "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", + "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", + "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz", + "integrity": "sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz", + "integrity": "sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", + "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", + "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz", + "integrity": "sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-identifier": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz", + "integrity": "sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", + "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz", + "integrity": "sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.12.tgz", + "integrity": "sha512-2vjjam0cum0miPkenUbQswKowuxs/NjMwIKEq0zwegRxXk12C9YOF9STXnaUptITOtOJHKHpzvvWYOjbm6tc0w==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-typescript": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.10.tgz", + "integrity": "sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==", + "dependencies": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.18.10", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.18.9", + "@babel/plugin-transform-classes": "^7.18.9", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.18.9", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.18.9", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.18.6", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.18.9", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.18.10", + "babel-plugin-polyfill-corejs2": "^0.3.2", + "babel-plugin-polyfill-corejs3": "^0.5.3", + "babel-plugin-polyfill-regenerator": "^0.4.0", + "core-js-compat": "^3.22.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.11.tgz", + "integrity": "sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.11", + "@babel/types": "^7.18.10", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", + "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", + "dependencies": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cush/relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cush/relative/-/relative-1.0.0.tgz", + "integrity": "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==" + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@fontsource/material-icons": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@fontsource/material-icons/-/material-icons-4.5.4.tgz", + "integrity": "sha512-YGmXkkEdu6EIgpFKNmB/nIXzZocwSmbI01Ninpmml8x8BT0M6RR++V1KqOfpzZ6Cw/FQ2/KYonQ3x4IY/4VRRA==" + }, + "node_modules/@fontsource/roboto-mono": { + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto-mono/-/roboto-mono-4.5.8.tgz", + "integrity": "sha512-AW44UkbQD0w1CT5mzDbsvhGZ6/bb0YmZzoELj6Sx8vcVEzcbYGUdt2Dtl5zqlOuYMWQFY1mniwWyVv+Bm/lVxw==" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@ivanv/vue-collapse-transition": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ivanv/vue-collapse-transition/-/vue-collapse-transition-1.0.2.tgz", + "integrity": "sha512-eWEameFXJM/1khcoKbITvKjYYXDP1WKQ/Xf9ItJVPoEjCiOdocR3AgDAERzDrNNg4oWK28gRGi+0ft8Te27zxw==", + "dev": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pixi/app": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/app/-/app-6.3.2.tgz", + "integrity": "sha512-V1jnhL92OPiquXtLxUeSZiVDd1mtjRnYpBKA958w29MrIRBx3Y6dgnvsaFZGGWBvSL//WRYV23iZKVL/jRGmmQ==", + "peerDependencies": { + "@pixi/core": "6.3.2", + "@pixi/display": "6.3.2" + } + }, + "node_modules/@pixi/constants": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.3.2.tgz", + "integrity": "sha512-sUE8QEJNl4vWUybS0YqpVUBWoOyLkr5bSj1+3mpmbWJTMVmLB2voFXo7XpSNCBlLH1SBN5flcgJlUWOCgNyATg==", + "peer": true + }, + "node_modules/@pixi/core": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.3.2.tgz", + "integrity": "sha512-91Fw0CbFpPtMKo5TG1wdaZGgR99lX87l15F7kgge7FM7ZR4EghLiJHU8whQ19f/UNOd8AG7mHD84lUB1VXXfoA==", + "dependencies": { + "@types/offscreencanvas": "^2019.6.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/pixijs" + }, + "peerDependencies": { + "@pixi/constants": "6.3.2", + "@pixi/math": "6.3.2", + "@pixi/runner": "6.3.2", + "@pixi/settings": "6.3.2", + "@pixi/ticker": "6.3.2", + "@pixi/utils": "6.3.2" + } + }, + "node_modules/@pixi/display": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.3.2.tgz", + "integrity": "sha512-D+WiM0BcyPK91RYxl7TXXVNz/5lOGs8Q6jtCMcWgTHwCXxWPOHFnNZ4KPJZpUQ7me8Tl2u+c9hfB5Oh1+17r/Q==", + "peer": true, + "peerDependencies": { + "@pixi/math": "6.3.2", + "@pixi/settings": "6.3.2", + "@pixi/utils": "6.3.2" + } + }, + "node_modules/@pixi/math": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.3.2.tgz", + "integrity": "sha512-REXrCKQaT2shJ3p2Rpq1ZYV4iUeAOUFKnLN2KteQWtB5HQpB8b+w5xBGI+TcnY0FUhx92fbKPYTTvCftNZF4Jw==", + "peer": true + }, + "node_modules/@pixi/particle-emitter": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@pixi/particle-emitter/-/particle-emitter-5.0.7.tgz", + "integrity": "sha512-g0vf+z2pFr+znJEzAii6T7CfMAKsCZuRc8bVY2znJDYxEKoAuU+XuqzHtOkGeR/VuiNCuJhMFLh+BDfXN4Fubw==", + "peerDependencies": { + "@pixi/constants": "^6.0.4", + "@pixi/core": "^6.0.4", + "@pixi/display": "^6.0.4", + "@pixi/math": "^6.0.4", + "@pixi/sprite": "^6.0.4", + "@pixi/ticker": "^6.0.4" + } + }, + "node_modules/@pixi/runner": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.3.2.tgz", + "integrity": "sha512-Sspv4VTiV51GwoIg+WudHZHpT3ad5ukW20OLOR+eDOSLbgQEMfj4cTVRg27TvM/QZ/5LxeN3FqwWV+kiWpqCnw==", + "peer": true + }, + "node_modules/@pixi/settings": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.3.2.tgz", + "integrity": "sha512-i5cLDUWFnRub3LPa3x7IzkH8MjSwPHyHWzIZKG5t8RiCfbhVfhWGEdKO9AYp8yO/xcf7AqtPK4mikXziL48tXA==", + "peer": true, + "dependencies": { + "ismobilejs": "^1.1.0" + } + }, + "node_modules/@pixi/sprite": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.3.2.tgz", + "integrity": "sha512-T1KJ8l2f8Otn6Se6h4b2pz2nrUSe59Pnmj2WIzgBisM245h7dGATs05MisMaLV6Lg/3gTBTxsLBmKsbDSQqbNw==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.3.2", + "@pixi/core": "6.3.2", + "@pixi/display": "6.3.2", + "@pixi/math": "6.3.2", + "@pixi/settings": "6.3.2", + "@pixi/utils": "6.3.2" + } + }, + "node_modules/@pixi/ticker": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.3.2.tgz", + "integrity": "sha512-Au9IO85zCOOCz50aJALFxJ2C8gbgxvD0dSNm7A5FauanJbxDcctIyrW6I51nNyHyeLIUFEkuD2jE/DmcXsXnpw==", + "peerDependencies": { + "@pixi/settings": "6.3.2" + } + }, + "node_modules/@pixi/utils": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.3.2.tgz", + "integrity": "sha512-VpB403kfqwXK9w7Qb6ex0aW0g6pWI/t43F2Z8CA/lAfYcN3O0XoxDucvmkLTQWsMtYn+Yf7YhAcLV5SemKwP0A==", + "peer": true, + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.2", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, + "peerDependencies": { + "@pixi/constants": "6.3.2", + "@pixi/settings": "6.3.2" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-babel/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-babel/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz", + "integrity": "sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA==", + "dev": true + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", + "dev": true + }, + "node_modules/@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/earcut": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.1.tgz", + "integrity": "sha512-w8oigUCDjElRHRRrMvn/spybSMyX8MTkKA5Dv+tS1IE/TgmNZPqUYtvYBXGY8cieSE66gm+szeK+bnbxC2xHTQ==", + "peer": true + }, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/lz-string": { + "version": "1.3.34", + "resolved": "https://registry.npmjs.org/@types/lz-string/-/lz-string-1.3.34.tgz", + "integrity": "sha512-j6G1e8DULJx3ONf6NdR5JiR2ZY3K3PaaqiEuKYkLQO0Czfi1AzrtjfnfCROyWGeDd5IVMKCwsgSmMip9OWijow==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.9.tgz", + "integrity": "sha512-0N5Y1XAdcl865nDdjbO0m3T6FdmQ4ijE89/urOHLREyTXbpMWbSafx9y7XIsgWGtwUP2iYTinLyyW3FatAxBLQ==" + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.0", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==" + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz", + "integrity": "sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.33.1", + "@typescript-eslint/type-utils": "5.33.1", + "@typescript-eslint/utils": "5.33.1", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.1.tgz", + "integrity": "sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.33.1", + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/typescript-estree": "5.33.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz", + "integrity": "sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/visitor-keys": "5.33.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz", + "integrity": "sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.33.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.33.1.tgz", + "integrity": "sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz", + "integrity": "sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/visitor-keys": "5.33.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.1.tgz", + "integrity": "sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.33.1", + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/typescript-estree": "5.33.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz", + "integrity": "sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.33.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.4.tgz", + "integrity": "sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg==", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "vite": "^2.5.10", + "vue": "^3.2.25" + } + }, + "node_modules/@vitejs/plugin-vue-jsx": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-1.3.10.tgz", + "integrity": "sha512-Cf5zznh4yNMiEMBfTOztaDVDmK1XXfgxClzOSUVUc8WAmHzogrCUeM8B05ABzuGtg0D1amfng+mUmSIOFGP3Pw==", + "dependencies": { + "@babel/core": "^7.17.9", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.16.8", + "@rollup/pluginutils": "^4.2.0", + "@vue/babel-plugin-jsx": "^1.1.1", + "hash-sum": "^2.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@volar/code-gen": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/code-gen/-/code-gen-0.38.9.tgz", + "integrity": "sha512-n6LClucfA+37rQeskvh9vDoZV1VvCVNy++MAPKj2dT4FT+Fbmty/SDQqnsEBtdEe6E3OQctFvA/IcKsx3Mns0A==", + "dev": true, + "dependencies": { + "@volar/source-map": "0.38.9" + } + }, + "node_modules/@volar/source-map": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-0.38.9.tgz", + "integrity": "sha512-ba0UFoHDYry+vwKdgkWJ6xlQT+8TFtZg1zj9tSjj4PykW1JZDuM0xplMotLun4h3YOoYfY9K1huY5gvxmrNLIw==", + "dev": true + }, + "node_modules/@volar/vue-code-gen": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/vue-code-gen/-/vue-code-gen-0.38.9.tgz", + "integrity": "sha512-tzj7AoarFBKl7e41MR006ncrEmNPHALuk8aG4WdDIaG387X5//5KhWC5Ff3ZfB2InGSeNT+CVUd74M0gS20rjA==", + "dev": true, + "dependencies": { + "@volar/code-gen": "0.38.9", + "@volar/source-map": "0.38.9", + "@vue/compiler-core": "^3.2.37", + "@vue/compiler-dom": "^3.2.37", + "@vue/shared": "^3.2.37" + } + }, + "node_modules/@volar/vue-typescript": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-0.38.9.tgz", + "integrity": "sha512-iJMQGU91ADi98u8V1vXd2UBmELDAaeSP0ZJaFjwosClQdKlJQYc6MlxxKfXBZisHqfbhdtrGRyaryulnYtliZw==", + "dev": true, + "dependencies": { + "@volar/code-gen": "0.38.9", + "@volar/source-map": "0.38.9", + "@volar/vue-code-gen": "0.38.9", + "@vue/compiler-sfc": "^3.2.37", + "@vue/reactivity": "^3.2.37" + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", + "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "@vue/babel-helper-vue-transform-on": "^1.0.2", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz", + "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.37", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", + "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", + "dependencies": { + "@vue/compiler-core": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", + "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.37", + "@vue/compiler-dom": "3.2.37", + "@vue/compiler-ssr": "3.2.37", + "@vue/reactivity-transform": "3.2.37", + "@vue/shared": "3.2.37", + "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.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", + "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", + "dependencies": { + "@vue/compiler-dom": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "node_modules/@vue/eslint-config-prettier": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-7.0.0.tgz", + "integrity": "sha512-/CTc6ML3Wta1tCe1gUeO0EYnVXfo3nJXsIhZ8WJr3sov+cGASr6yuiibJTL6lmIBm7GobopToOuB3B6AWyV0Iw==", + "dev": true, + "dependencies": { + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^4.0.0" + }, + "peerDependencies": { + "eslint": ">= 7.28.0", + "prettier": ">= 2.0.0" + } + }, + "node_modules/@vue/eslint-config-typescript": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-10.0.0.tgz", + "integrity": "sha512-F94cL8ug3FaYXlCfU5/wiGjk1qeadmoBpRGAOBq+qre3Smdupa59dd6ZJrsfRODpsMPyTG7330juMDsUvpZ3Rw==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/parser": "^5.0.0", + "vue-eslint-parser": "^8.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0", + "eslint-plugin-vue": "^8.0.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz", + "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", + "dependencies": { + "@vue/shared": "3.2.37" + } + }, + "node_modules/@vue/reactivity-transform": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", + "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.37", + "@vue/shared": "3.2.37", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz", + "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", + "dependencies": { + "@vue/reactivity": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", + "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", + "dependencies": { + "@vue/runtime-core": "3.2.37", + "@vue/shared": "3.2.37", + "csstype": "^2.6.8" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz", + "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", + "dependencies": { + "@vue/compiler-ssr": "3.2.37", + "@vue/shared": "3.2.37" + }, + "peerDependencies": { + "vue": "3.2.37" + } + }, + "node_modules/@vue/shared": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz", + "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/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/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/amator/-/amator-1.1.0.tgz", + "integrity": "sha512-V5+aH8pe+Z3u/UG3L3pG3BaFQGXAyXHVQDroRwjPHdh08bcUEchAVsU1MCuJSCaU5o60wTK6KaE6te5memzgYw==", + "dependencies": { + "bezier-easing": "^2.0.3" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz", + "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==", + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.2", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz", + "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.2", + "core-js-compat": "^3.21.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz", + "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "peer": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001380", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001380.tgz", + "integrity": "sha512-OO+pPubxx16lkI7TVrbFpde8XHz66SMwstl1YWpg6uMGw56XnhYVwtPIjvX4kYpzwMwQKr4DDce394E03dQPGg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true + }, + "node_modules/core-js-compat": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.24.1.tgz", + "integrity": "sha512-XhdNAGeRnTpp8xbD+sR/HFDK9CbeeeqXT6TuofXh3urqEevzkWmLRgrVoykodsw8okqo2pu1BOmuCKrHx63zdw==", + "dependencies": { + "browserslist": "^4.21.3", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "peer": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/csstype": { + "version": "2.6.20", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz", + "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==" + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", + "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "dev": true + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", + "peer": true + }, + "node_modules/ejs": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.225", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz", + "integrity": "sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw==" + }, + "node_modules/entities": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", + "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", + "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.3", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-vue": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz", + "integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==", + "dev": true, + "peer": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.0.1", + "postcss-selector-parser": "^6.0.9", + "semver": "^7.3.5", + "vue-eslint-parser": "^8.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-vue/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", + "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "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/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "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==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-regex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", + "integrity": "sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==" + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "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==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-tags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.2.tgz", + "integrity": "sha512-jjKrT1EnyZewQ/gCBb/eyiYrhGzws2FeY92Yx8qT9S9GeQAmo4JFVIiWRIfKW/6Ob9A+UDAOW9j9jn58fy2HIg==" + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "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==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/ismobilejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==", + "peer": true + }, + "node_modules/jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", + "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.7.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.3.1", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "^7.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.8.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/local-pkg": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", + "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "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/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoevents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/nanoevents/-/nanoevents-6.0.2.tgz", + "integrity": "sha512-FRS2otuFcPPYDPYViNWQ42+1iZqbXydinkRHTHFxrF4a1CpBfmydR9zkI44WSXAXCyPrkcGtPk5CnpW6Y3lFKQ==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/ngraph.events": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz", + "integrity": "sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==" + }, + "node_modules/node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "peer": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", + "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", + "dev": true + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/panzoom": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/panzoom/-/panzoom-9.4.3.tgz", + "integrity": "sha512-xaxCpElcRbQsUtIdwlrZA90P90+BHip4Vda2BC8MEb4tkI05PmR6cKECdqUCZ85ZvBHjpI9htJrZBxV5Gp/q/w==", + "dependencies": { + "amator": "^1.1.0", + "ngraph.events": "^1.2.2", + "wheel": "^1.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", + "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "dev": true, + "dependencies": { + "entities": "^4.3.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "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/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-bytes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.0.0.tgz", + "integrity": "sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "peer": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/recrawl-sync": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", + "integrity": "sha512-E2sI4F25Fu2nrfV+KsnC7/qfk/spQIYXlonfQoS4rwxeNK5BjxnLPbWiRXHVXPwYBOTWtPX5765kTm/zJiL+LQ==", + "dependencies": { + "@cush/relative": "^1.0.0", + "glob-regex": "^0.3.0", + "slash": "^3.0.0", + "tslib": "^1.9.3" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz", + "integrity": "sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==" + }, + "node_modules/regjsparser": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "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/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.77.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz", + "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sortablejs": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", + "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==" + }, + "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/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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/string.prototype.matchall": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==" + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.2.4.tgz", + "integrity": "sha512-Vs3rhkUH6Qq1t5bqtb816oT+HeJTXfwt2cbPH17sWHIYKTotQIFPk3tf2fgqRrVyMDVOc1EnPgzIxfIulXVzwQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.3.tgz", + "integrity": "sha512-gRiUR8fuhUf0W9lzojPf1N1euJYA30ISebSfgca8z76FOvXtVXqd5ojEIaKLWbDQhAaC3ibxZIjqbyi4ybjcTw==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "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": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", + "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", + "dependencies": { + "json5": "^2.2.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", + "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "peer": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "peer": true + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/vite": { + "version": "2.9.15", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.15.tgz", + "integrity": "sha512-fzMt2jK4vQ3yK56te3Kqpkaeq9DkcZfBbzHwYpobasvgYmP2SoAr6Aic05CsB4CzCZbsDv4sujX3pkEGhLabVQ==", + "dependencies": { + "esbuild": "^0.14.27", + "postcss": "^8.4.13", + "resolve": "^1.22.0", + "rollup": ">=2.59.0 <2.78.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/vite-plugin-pwa": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.12.3.tgz", + "integrity": "sha512-gmYdIVXpmBuNjzbJFPZFzxWYrX4lHqwMAlOtjmXBbxApiHjx9QPXKQPJjSpeTeosLKvVbNcKSAAhfxMda0QVNQ==", + "dependencies": { + "debug": "^4.3.4", + "fast-glob": "^3.2.11", + "pretty-bytes": "^6.0.0", + "rollup": "^2.75.7", + "workbox-build": "^6.5.3", + "workbox-window": "^6.5.3" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.0.0 || ^3.0.0-0", + "workbox-build": "^6.4.0", + "workbox-window": "^6.4.0" + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-3.5.0.tgz", + "integrity": "sha512-NKIubr7gXgh/3uniQaOytSg+aKWPrjquP6anAy+zCWEn6h9fB8z2/qdlfQrTgZWaXJ2pHVlllrSdRZltHn9P4g==", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "recrawl-sync": "^2.0.3", + "tsconfig-paths": "^4.0.0" + }, + "peerDependencies": { + "vite": ">2.0.0-0" + } + }, + "node_modules/vitest": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.17.1.tgz", + "integrity": "sha512-d6NsFC6FPmZ5XdiSYfW5rwJ/b8060wqe2steNNlVbhO69HWma6CucIm5g7PXlCSkmKvrdEbUsZHPAarlH83VGw==", + "dev": true, + "dependencies": { + "@types/chai": "^4.3.1", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "chai": "^4.3.6", + "debug": "^4.3.4", + "local-pkg": "^0.4.1", + "tinypool": "^0.2.1", + "tinyspy": "^0.3.3", + "vite": "^2.9.12 || ^3.0.0-0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.16.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/ui": "*", + "c8": "*", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "c8": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz", + "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", + "dependencies": { + "@vue/compiler-dom": "3.2.37", + "@vue/compiler-sfc": "3.2.37", + "@vue/runtime-dom": "3.2.37", + "@vue/server-renderer": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "node_modules/vue-eslint-parser": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", + "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vue-next-select": { + "version": "2.10.4", + "resolved": "https://registry.npmjs.org/vue-next-select/-/vue-next-select-2.10.4.tgz", + "integrity": "sha512-9Lg1mD2h9w6mm4gkXPyVMWhOdUPtA/JF9VrNyo6mqjkh4ktGLVQpNhygVBCg13RFHdEq3iqawjeFmp3FJq+CUw==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-panzoom": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/vue-panzoom/-/vue-panzoom-1.1.6.tgz", + "integrity": "sha512-yEE60C/gnc5NGL6YBD++CErD820va7fkBJE5dCWZZzXX2aMGklj/UKmtqu1u5xDkuOIjnGUr412LNHwOOE711w==", + "dependencies": { + "panzoom": "^9.4.1" + } + }, + "node_modules/vue-textarea-autosize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vue-textarea-autosize/-/vue-textarea-autosize-1.1.1.tgz", + "integrity": "sha512-B33Mg5ZDEfj/whhoPBLg25qqAdGHGM2NjDT99Qi5MXRyeLmXb4C3s6EprAHqy3nU0cooWXFU+IekI5DpoEbnFg==", + "dependencies": { + "core-js": "^2.6.5" + } + }, + "node_modules/vue-toastification": { + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz", + "integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==", + "peerDependencies": { + "vue": "^3.0.2" + } + }, + "node_modules/vue-transition-expand": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vue-transition-expand/-/vue-transition-expand-0.1.0.tgz", + "integrity": "sha512-4UKkK/ILk+Qh3WWJoupt7pXfzpjvb7vTQTaVUhnkr+FeXArndJVDyIn2eWIn7i37cVFXKu2jsDR47QELOCq/gQ==", + "dependencies": { + "vue": "^2.5.16" + } + }, + "node_modules/vue-transition-expand/node_modules/@vue/compiler-sfc": { + "version": "2.7.9", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.9.tgz", + "integrity": "sha512-TD2FvT0fPUezw5RVP4tfwTZnKHP0QjeEUb39y7tORvOJQTjbOuHJEk4GPHUPsRaTeQ8rjuKjntyrYcEIx+ODxg==", + "dependencies": { + "@babel/parser": "^7.18.4", + "postcss": "^8.4.14", + "source-map": "^0.6.1" + } + }, + "node_modules/vue-transition-expand/node_modules/csstype": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", + "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + }, + "node_modules/vue-transition-expand/node_modules/vue": { + "version": "2.7.9", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.9.tgz", + "integrity": "sha512-GeWCvAUkjzD5q4A3vgi8ka5r9bM6g8fmNmx/9VnHDKCaEzBcoVw+7UcQktZHrJ2jhlI+Zv8L57pMCIwM4h4MWg==", + "dependencies": { + "@vue/compiler-sfc": "2.7.9", + "csstype": "^3.1.0" + } + }, + "node_modules/vue-tsc": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.38.9.tgz", + "integrity": "sha512-Yoy5phgvGqyF98Fb4mYqboR4Q149jrdcGv5kSmufXJUq++RZJ2iMVG0g6zl+v3t4ORVWkQmRpsV4x2szufZ0LQ==", + "dev": true, + "dependencies": { + "@volar/vue-typescript": "0.38.9" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/vuedraggable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz", + "integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==", + "dependencies": { + "sortablejs": "1.14.0" + }, + "peerDependencies": { + "vue": "^3.0.1" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wheel": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wheel/-/wheel-1.0.0.tgz", + "integrity": "sha512-XiCMHibOiqalCQ+BaNSwRoZ9FDTAvOsXxGHXChBugewDj7HC8VBIER71dEOiRH1fSdLbRCQzngKTSiZ06ZQzeA==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", + "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", + "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-build": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz", + "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.5.4", + "workbox-broadcast-update": "6.5.4", + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-google-analytics": "6.5.4", + "workbox-navigation-preload": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-range-requests": "6.5.4", + "workbox-recipes": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", + "workbox-streams": "6.5.4", + "workbox-sw": "6.5.4", + "workbox-window": "6.5.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", + "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-core": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" + }, + "node_modules/workbox-expiration": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz", + "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", + "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", + "dependencies": { + "workbox-background-sync": "6.5.4", + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", + "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-precaching": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz", + "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", + "dependencies": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", + "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-recipes": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz", + "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", + "dependencies": { + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "node_modules/workbox-routing": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-strategies": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-streams": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz", + "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", + "dependencies": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4" + } + }, + "node_modules/workbox-sw": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz", + "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" + }, + "node_modules/workbox-window": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz", + "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.5.4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", + "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==" + }, + "@babel/core": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", + "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.10", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.10", + "@babel/types": "^7.18.10", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + } + }, + "@babel/generator": { + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz", + "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==", + "requires": { + "@babel/types": "^7.18.10", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", + "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + "requires": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.20.2", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz", + "integrity": "sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz", + "integrity": "sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz", + "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==", + "requires": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", + "requires": { + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", + "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", + "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==" + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-replace-supers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz", + "integrity": "sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-simple-access": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==" + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + }, + "@babel/helper-wrap-function": { + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz", + "integrity": "sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w==", + "requires": { + "@babel/helper-function-name": "^7.18.9", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.11", + "@babel/types": "^7.18.10" + } + }, + "@babel/helpers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", + "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", + "requires": { + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.11.tgz", + "integrity": "sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==" + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz", + "integrity": "sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", + "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "requires": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", + "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", + "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", + "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz", + "integrity": "sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz", + "integrity": "sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "requires": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", + "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", + "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz", + "integrity": "sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A==", + "requires": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-identifier": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz", + "integrity": "sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", + "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz", + "integrity": "sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.12.tgz", + "integrity": "sha512-2vjjam0cum0miPkenUbQswKowuxs/NjMwIKEq0zwegRxXk12C9YOF9STXnaUptITOtOJHKHpzvvWYOjbm6tc0w==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-typescript": "^7.18.6" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/preset-env": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.10.tgz", + "integrity": "sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==", + "requires": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.18.10", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.18.9", + "@babel/plugin-transform-classes": "^7.18.9", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.18.9", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.18.9", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.18.6", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.18.9", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.18.10", + "babel-plugin-polyfill-corejs2": "^0.3.2", + "babel-plugin-polyfill-corejs3": "^0.5.3", + "babel-plugin-polyfill-regenerator": "^0.4.0", + "core-js-compat": "^3.22.1", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/runtime": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.11.tgz", + "integrity": "sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.11", + "@babel/types": "^7.18.10", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", + "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", + "requires": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", + "to-fast-properties": "^2.0.0" + } + }, + "@cush/relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cush/relative/-/relative-1.0.0.tgz", + "integrity": "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==" + }, + "@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "optional": true + }, + "@eslint/eslintrc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "@fontsource/material-icons": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@fontsource/material-icons/-/material-icons-4.5.4.tgz", + "integrity": "sha512-YGmXkkEdu6EIgpFKNmB/nIXzZocwSmbI01Ninpmml8x8BT0M6RR++V1KqOfpzZ6Cw/FQ2/KYonQ3x4IY/4VRRA==" + }, + "@fontsource/roboto-mono": { + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto-mono/-/roboto-mono-4.5.8.tgz", + "integrity": "sha512-AW44UkbQD0w1CT5mzDbsvhGZ6/bb0YmZzoELj6Sx8vcVEzcbYGUdt2Dtl5zqlOuYMWQFY1mniwWyVv+Bm/lVxw==" + }, + "@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@ivanv/vue-collapse-transition": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ivanv/vue-collapse-transition/-/vue-collapse-transition-1.0.2.tgz", + "integrity": "sha512-eWEameFXJM/1khcoKbITvKjYYXDP1WKQ/Xf9ItJVPoEjCiOdocR3AgDAERzDrNNg4oWK28gRGi+0ft8Te27zxw==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pixi/app": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/app/-/app-6.3.2.tgz", + "integrity": "sha512-V1jnhL92OPiquXtLxUeSZiVDd1mtjRnYpBKA958w29MrIRBx3Y6dgnvsaFZGGWBvSL//WRYV23iZKVL/jRGmmQ==", + "requires": {} + }, + "@pixi/constants": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.3.2.tgz", + "integrity": "sha512-sUE8QEJNl4vWUybS0YqpVUBWoOyLkr5bSj1+3mpmbWJTMVmLB2voFXo7XpSNCBlLH1SBN5flcgJlUWOCgNyATg==", + "peer": true + }, + "@pixi/core": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.3.2.tgz", + "integrity": "sha512-91Fw0CbFpPtMKo5TG1wdaZGgR99lX87l15F7kgge7FM7ZR4EghLiJHU8whQ19f/UNOd8AG7mHD84lUB1VXXfoA==", + "requires": { + "@types/offscreencanvas": "^2019.6.4" + } + }, + "@pixi/display": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.3.2.tgz", + "integrity": "sha512-D+WiM0BcyPK91RYxl7TXXVNz/5lOGs8Q6jtCMcWgTHwCXxWPOHFnNZ4KPJZpUQ7me8Tl2u+c9hfB5Oh1+17r/Q==", + "peer": true, + "requires": {} + }, + "@pixi/math": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.3.2.tgz", + "integrity": "sha512-REXrCKQaT2shJ3p2Rpq1ZYV4iUeAOUFKnLN2KteQWtB5HQpB8b+w5xBGI+TcnY0FUhx92fbKPYTTvCftNZF4Jw==", + "peer": true + }, + "@pixi/particle-emitter": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@pixi/particle-emitter/-/particle-emitter-5.0.7.tgz", + "integrity": "sha512-g0vf+z2pFr+znJEzAii6T7CfMAKsCZuRc8bVY2znJDYxEKoAuU+XuqzHtOkGeR/VuiNCuJhMFLh+BDfXN4Fubw==", + "requires": {} + }, + "@pixi/runner": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.3.2.tgz", + "integrity": "sha512-Sspv4VTiV51GwoIg+WudHZHpT3ad5ukW20OLOR+eDOSLbgQEMfj4cTVRg27TvM/QZ/5LxeN3FqwWV+kiWpqCnw==", + "peer": true + }, + "@pixi/settings": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.3.2.tgz", + "integrity": "sha512-i5cLDUWFnRub3LPa3x7IzkH8MjSwPHyHWzIZKG5t8RiCfbhVfhWGEdKO9AYp8yO/xcf7AqtPK4mikXziL48tXA==", + "peer": true, + "requires": { + "ismobilejs": "^1.1.0" + } + }, + "@pixi/sprite": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.3.2.tgz", + "integrity": "sha512-T1KJ8l2f8Otn6Se6h4b2pz2nrUSe59Pnmj2WIzgBisM245h7dGATs05MisMaLV6Lg/3gTBTxsLBmKsbDSQqbNw==", + "peer": true, + "requires": {} + }, + "@pixi/ticker": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.3.2.tgz", + "integrity": "sha512-Au9IO85zCOOCz50aJALFxJ2C8gbgxvD0dSNm7A5FauanJbxDcctIyrW6I51nNyHyeLIUFEkuD2jE/DmcXsXnpw==", + "requires": {} + }, + "@pixi/utils": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.3.2.tgz", + "integrity": "sha512-VpB403kfqwXK9w7Qb6ex0aW0g6pWI/t43F2Z8CA/lAfYcN3O0XoxDucvmkLTQWsMtYn+Yf7YhAcLV5SemKwP0A==", + "peer": true, + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.2", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + } + } + }, + "@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + } + } + }, + "@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + } + } + }, + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + }, + "@rushstack/eslint-patch": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz", + "integrity": "sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA==", + "dev": true + }, + "@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "requires": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true + }, + "@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", + "dev": true + }, + "@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, + "@types/earcut": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.1.tgz", + "integrity": "sha512-w8oigUCDjElRHRRrMvn/spybSMyX8MTkKA5Dv+tS1IE/TgmNZPqUYtvYBXGY8cieSE66gm+szeK+bnbxC2xHTQ==", + "peer": true + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/lz-string": { + "version": "1.3.34", + "resolved": "https://registry.npmjs.org/@types/lz-string/-/lz-string-1.3.34.tgz", + "integrity": "sha512-j6G1e8DULJx3ONf6NdR5JiR2ZY3K3PaaqiEuKYkLQO0Czfi1AzrtjfnfCROyWGeDd5IVMKCwsgSmMip9OWijow==", + "dev": true + }, + "@types/node": { + "version": "18.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.9.tgz", + "integrity": "sha512-0N5Y1XAdcl865nDdjbO0m3T6FdmQ4ijE89/urOHLREyTXbpMWbSafx9y7XIsgWGtwUP2iYTinLyyW3FatAxBLQ==" + }, + "@types/offscreencanvas": { + "version": "2019.7.0", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==" + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "requires": { + "@types/node": "*" + } + }, + "@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz", + "integrity": "sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.33.1", + "@typescript-eslint/type-utils": "5.33.1", + "@typescript-eslint/utils": "5.33.1", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.1.tgz", + "integrity": "sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.33.1", + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/typescript-estree": "5.33.1", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz", + "integrity": "sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/visitor-keys": "5.33.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz", + "integrity": "sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.33.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.33.1.tgz", + "integrity": "sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz", + "integrity": "sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/visitor-keys": "5.33.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.1.tgz", + "integrity": "sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.33.1", + "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/typescript-estree": "5.33.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz", + "integrity": "sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.33.1", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@vitejs/plugin-vue": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.4.tgz", + "integrity": "sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg==", + "requires": {} + }, + "@vitejs/plugin-vue-jsx": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-1.3.10.tgz", + "integrity": "sha512-Cf5zznh4yNMiEMBfTOztaDVDmK1XXfgxClzOSUVUc8WAmHzogrCUeM8B05ABzuGtg0D1amfng+mUmSIOFGP3Pw==", + "requires": { + "@babel/core": "^7.17.9", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.16.8", + "@rollup/pluginutils": "^4.2.0", + "@vue/babel-plugin-jsx": "^1.1.1", + "hash-sum": "^2.0.0" + } + }, + "@volar/code-gen": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/code-gen/-/code-gen-0.38.9.tgz", + "integrity": "sha512-n6LClucfA+37rQeskvh9vDoZV1VvCVNy++MAPKj2dT4FT+Fbmty/SDQqnsEBtdEe6E3OQctFvA/IcKsx3Mns0A==", + "dev": true, + "requires": { + "@volar/source-map": "0.38.9" + } + }, + "@volar/source-map": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-0.38.9.tgz", + "integrity": "sha512-ba0UFoHDYry+vwKdgkWJ6xlQT+8TFtZg1zj9tSjj4PykW1JZDuM0xplMotLun4h3YOoYfY9K1huY5gvxmrNLIw==", + "dev": true + }, + "@volar/vue-code-gen": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/vue-code-gen/-/vue-code-gen-0.38.9.tgz", + "integrity": "sha512-tzj7AoarFBKl7e41MR006ncrEmNPHALuk8aG4WdDIaG387X5//5KhWC5Ff3ZfB2InGSeNT+CVUd74M0gS20rjA==", + "dev": true, + "requires": { + "@volar/code-gen": "0.38.9", + "@volar/source-map": "0.38.9", + "@vue/compiler-core": "^3.2.37", + "@vue/compiler-dom": "^3.2.37", + "@vue/shared": "^3.2.37" + } + }, + "@volar/vue-typescript": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-0.38.9.tgz", + "integrity": "sha512-iJMQGU91ADi98u8V1vXd2UBmELDAaeSP0ZJaFjwosClQdKlJQYc6MlxxKfXBZisHqfbhdtrGRyaryulnYtliZw==", + "dev": true, + "requires": { + "@volar/code-gen": "0.38.9", + "@volar/source-map": "0.38.9", + "@volar/vue-code-gen": "0.38.9", + "@vue/compiler-sfc": "^3.2.37", + "@vue/reactivity": "^3.2.37" + } + }, + "@vue/babel-helper-vue-transform-on": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==" + }, + "@vue/babel-plugin-jsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", + "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "@vue/babel-helper-vue-transform-on": "^1.0.2", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + } + }, + "@vue/compiler-core": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz", + "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.37", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-dom": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", + "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", + "requires": { + "@vue/compiler-core": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "@vue/compiler-sfc": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", + "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.37", + "@vue/compiler-dom": "3.2.37", + "@vue/compiler-ssr": "3.2.37", + "@vue/reactivity-transform": "3.2.37", + "@vue/shared": "3.2.37", + "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.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", + "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", + "requires": { + "@vue/compiler-dom": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "@vue/eslint-config-prettier": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-7.0.0.tgz", + "integrity": "sha512-/CTc6ML3Wta1tCe1gUeO0EYnVXfo3nJXsIhZ8WJr3sov+cGASr6yuiibJTL6lmIBm7GobopToOuB3B6AWyV0Iw==", + "dev": true, + "requires": { + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^4.0.0" + } + }, + "@vue/eslint-config-typescript": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-10.0.0.tgz", + "integrity": "sha512-F94cL8ug3FaYXlCfU5/wiGjk1qeadmoBpRGAOBq+qre3Smdupa59dd6ZJrsfRODpsMPyTG7330juMDsUvpZ3Rw==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/parser": "^5.0.0", + "vue-eslint-parser": "^8.0.0" + } + }, + "@vue/reactivity": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz", + "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", + "requires": { + "@vue/shared": "3.2.37" + } + }, + "@vue/reactivity-transform": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", + "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.37", + "@vue/shared": "3.2.37", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "@vue/runtime-core": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz", + "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", + "requires": { + "@vue/reactivity": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "@vue/runtime-dom": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", + "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", + "requires": { + "@vue/runtime-core": "3.2.37", + "@vue/shared": "3.2.37", + "csstype": "^2.6.8" + } + }, + "@vue/server-renderer": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz", + "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", + "requires": { + "@vue/compiler-ssr": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "@vue/shared": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz", + "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/amator/-/amator-1.1.0.tgz", + "integrity": "sha512-V5+aH8pe+Z3u/UG3L3pG3BaFQGXAyXHVQDroRwjPHdh08bcUEchAVsU1MCuJSCaU5o60wTK6KaE6te5memzgYw==", + "requires": { + "bezier-easing": "^2.0.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz", + "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==", + "requires": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.2", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz", + "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.2", + "core-js-compat": "^3.21.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz", + "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "peer": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "browserslist": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "requires": { + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "caniuse-lite": { + "version": "1.0.30001380", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001380.tgz", + "integrity": "sha512-OO+pPubxx16lkI7TVrbFpde8XHz66SMwstl1YWpg6uMGw56XnhYVwtPIjvX4kYpzwMwQKr4DDce394E03dQPGg==" + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + }, + "core-js-compat": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.24.1.tgz", + "integrity": "sha512-XhdNAGeRnTpp8xbD+sR/HFDK9CbeeeqXT6TuofXh3urqEevzkWmLRgrVoykodsw8okqo2pu1BOmuCKrHx63zdw==", + "requires": { + "browserslist": "^4.21.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + } + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "peer": true + }, + "cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "csstype": { + "version": "2.6.20", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz", + "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==" + }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decimal.js": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", + "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "requires": { + "webidl-conversions": "^7.0.0" + } + }, + "earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", + "peer": true + }, + "ejs": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "requires": { + "jake": "^10.8.5" + } + }, + "electron-to-chromium": { + "version": "1.4.225", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz", + "integrity": "sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw==" + }, + "entities": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", + "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==", + "dev": true + }, + "es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "requires": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "optional": true + }, + "esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "optional": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", + "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.3", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "requires": {} + }, + "eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-vue": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz", + "integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==", + "dev": true, + "peer": true, + "requires": { + "eslint-utils": "^3.0.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.0.1", + "postcss-selector-parser": "^6.0.9", + "semver": "^7.3.5", + "vue-eslint-parser": "^8.0.1" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", + "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "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==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "requires": { + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "glob-regex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", + "integrity": "sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==" + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^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==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "html-tags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==" + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "idb": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.2.tgz", + "integrity": "sha512-jjKrT1EnyZewQ/gCBb/eyiYrhGzws2FeY92Yx8qT9S9GeQAmo4JFVIiWRIfKW/6Ob9A+UDAOW9j9jn58fy2HIg==" + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "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==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "ismobilejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==", + "peer": true + }, + "jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsdom": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", + "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "acorn": "^8.7.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.3.1", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "^7.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.8.0", + "xml-name-validator": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "local-pkg": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", + "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==" + }, + "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" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoevents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/nanoevents/-/nanoevents-6.0.2.tgz", + "integrity": "sha512-FRS2otuFcPPYDPYViNWQ42+1iZqbXydinkRHTHFxrF4a1CpBfmydR9zkI44WSXAXCyPrkcGtPk5CnpW6Y3lFKQ==" + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "ngraph.events": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz", + "integrity": "sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==" + }, + "node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "peer": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "nwsapi": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", + "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", + "dev": true + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "panzoom": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/panzoom/-/panzoom-9.4.3.tgz", + "integrity": "sha512-xaxCpElcRbQsUtIdwlrZA90P90+BHip4Vda2BC8MEb4tkI05PmR6cKECdqUCZ85ZvBHjpI9htJrZBxV5Gp/q/w==", + "requires": { + "amator": "^1.1.0", + "ngraph.events": "^1.2.2", + "wheel": "^1.0.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse5": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", + "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "dev": true, + "requires": { + "entities": "^4.3.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "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==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "peer": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-bytes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.0.0.tgz", + "integrity": "sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==" + }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "peer": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "recrawl-sync": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", + "integrity": "sha512-E2sI4F25Fu2nrfV+KsnC7/qfk/spQIYXlonfQoS4rwxeNK5BjxnLPbWiRXHVXPwYBOTWtPX5765kTm/zJiL+LQ==", + "requires": { + "@cush/relative": "^1.0.0", + "glob-regex": "^0.3.0", + "slash": "^3.0.0", + "tslib": "^1.9.3" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "regenerate-unicode-properties": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "regenerator-transform": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "regexpu-core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz", + "integrity": "sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==", + "requires": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + } + }, + "regjsgen": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==" + }, + "regjsparser": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + } + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "2.77.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz", + "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "sortablejs": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", + "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==" + }, + "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==" + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "string.prototype.matchall": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.1", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + }, + "strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "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==" + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==" + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" + }, + "tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "requires": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + } + }, + "terser": { + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "tinypool": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.2.4.tgz", + "integrity": "sha512-Vs3rhkUH6Qq1t5bqtb816oT+HeJTXfwt2cbPH17sWHIYKTotQIFPk3tf2fgqRrVyMDVOc1EnPgzIxfIulXVzwQ==", + "dev": true + }, + "tinyspy": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.3.tgz", + "integrity": "sha512-gRiUR8fuhUf0W9lzojPf1N1euJYA30ISebSfgca8z76FOvXtVXqd5ojEIaKLWbDQhAaC3ibxZIjqbyi4ybjcTw==", + "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": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "tsconfig-paths": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", + "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", + "requires": { + "json5": "^2.2.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" + }, + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + }, + "unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==" + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + }, + "update-browserslist-db": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", + "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "peer": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "peer": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "peer": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "vite": { + "version": "2.9.15", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.15.tgz", + "integrity": "sha512-fzMt2jK4vQ3yK56te3Kqpkaeq9DkcZfBbzHwYpobasvgYmP2SoAr6Aic05CsB4CzCZbsDv4sujX3pkEGhLabVQ==", + "requires": { + "esbuild": "^0.14.27", + "fsevents": "~2.3.2", + "postcss": "^8.4.13", + "resolve": "^1.22.0", + "rollup": ">=2.59.0 <2.78.0" + } + }, + "vite-plugin-pwa": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.12.3.tgz", + "integrity": "sha512-gmYdIVXpmBuNjzbJFPZFzxWYrX4lHqwMAlOtjmXBbxApiHjx9QPXKQPJjSpeTeosLKvVbNcKSAAhfxMda0QVNQ==", + "requires": { + "debug": "^4.3.4", + "fast-glob": "^3.2.11", + "pretty-bytes": "^6.0.0", + "rollup": "^2.75.7", + "workbox-build": "^6.5.3", + "workbox-window": "^6.5.3" + } + }, + "vite-tsconfig-paths": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-3.5.0.tgz", + "integrity": "sha512-NKIubr7gXgh/3uniQaOytSg+aKWPrjquP6anAy+zCWEn6h9fB8z2/qdlfQrTgZWaXJ2pHVlllrSdRZltHn9P4g==", + "requires": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "recrawl-sync": "^2.0.3", + "tsconfig-paths": "^4.0.0" + } + }, + "vitest": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.17.1.tgz", + "integrity": "sha512-d6NsFC6FPmZ5XdiSYfW5rwJ/b8060wqe2steNNlVbhO69HWma6CucIm5g7PXlCSkmKvrdEbUsZHPAarlH83VGw==", + "dev": true, + "requires": { + "@types/chai": "^4.3.1", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "chai": "^4.3.6", + "debug": "^4.3.4", + "local-pkg": "^0.4.1", + "tinypool": "^0.2.1", + "tinyspy": "^0.3.3", + "vite": "^2.9.12 || ^3.0.0-0" + } + }, + "vue": { + "version": "3.2.37", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz", + "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", + "requires": { + "@vue/compiler-dom": "3.2.37", + "@vue/compiler-sfc": "3.2.37", + "@vue/runtime-dom": "3.2.37", + "@vue/server-renderer": "3.2.37", + "@vue/shared": "3.2.37" + } + }, + "vue-eslint-parser": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", + "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + }, + "dependencies": { + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "vue-next-select": { + "version": "2.10.4", + "resolved": "https://registry.npmjs.org/vue-next-select/-/vue-next-select-2.10.4.tgz", + "integrity": "sha512-9Lg1mD2h9w6mm4gkXPyVMWhOdUPtA/JF9VrNyo6mqjkh4ktGLVQpNhygVBCg13RFHdEq3iqawjeFmp3FJq+CUw==", + "requires": {} + }, + "vue-panzoom": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/vue-panzoom/-/vue-panzoom-1.1.6.tgz", + "integrity": "sha512-yEE60C/gnc5NGL6YBD++CErD820va7fkBJE5dCWZZzXX2aMGklj/UKmtqu1u5xDkuOIjnGUr412LNHwOOE711w==", + "requires": { + "panzoom": "^9.4.1" + } + }, + "vue-textarea-autosize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vue-textarea-autosize/-/vue-textarea-autosize-1.1.1.tgz", + "integrity": "sha512-B33Mg5ZDEfj/whhoPBLg25qqAdGHGM2NjDT99Qi5MXRyeLmXb4C3s6EprAHqy3nU0cooWXFU+IekI5DpoEbnFg==", + "requires": { + "core-js": "^2.6.5" + } + }, + "vue-toastification": { + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz", + "integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==", + "requires": {} + }, + "vue-transition-expand": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vue-transition-expand/-/vue-transition-expand-0.1.0.tgz", + "integrity": "sha512-4UKkK/ILk+Qh3WWJoupt7pXfzpjvb7vTQTaVUhnkr+FeXArndJVDyIn2eWIn7i37cVFXKu2jsDR47QELOCq/gQ==", + "requires": { + "vue": "^2.5.16" + }, + "dependencies": { + "@vue/compiler-sfc": { + "version": "2.7.9", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.9.tgz", + "integrity": "sha512-TD2FvT0fPUezw5RVP4tfwTZnKHP0QjeEUb39y7tORvOJQTjbOuHJEk4GPHUPsRaTeQ8rjuKjntyrYcEIx+ODxg==", + "requires": { + "@babel/parser": "^7.18.4", + "postcss": "^8.4.14", + "source-map": "^0.6.1" + } + }, + "csstype": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", + "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + }, + "vue": { + "version": "2.7.9", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.9.tgz", + "integrity": "sha512-GeWCvAUkjzD5q4A3vgi8ka5r9bM6g8fmNmx/9VnHDKCaEzBcoVw+7UcQktZHrJ2jhlI+Zv8L57pMCIwM4h4MWg==", + "requires": { + "@vue/compiler-sfc": "2.7.9", + "csstype": "^3.1.0" + } + } + } + }, + "vue-tsc": { + "version": "0.38.9", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.38.9.tgz", + "integrity": "sha512-Yoy5phgvGqyF98Fb4mYqboR4Q149jrdcGv5kSmufXJUq++RZJ2iMVG0g6zl+v3t4ORVWkQmRpsV4x2szufZ0LQ==", + "dev": true, + "requires": { + "@volar/vue-typescript": "0.38.9" + } + }, + "vuedraggable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz", + "integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==", + "requires": { + "sortablejs": "1.14.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, + "wheel": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wheel/-/wheel-1.0.0.tgz", + "integrity": "sha512-XiCMHibOiqalCQ+BaNSwRoZ9FDTAvOsXxGHXChBugewDj7HC8VBIER71dEOiRH1fSdLbRCQzngKTSiZ06ZQzeA==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "workbox-background-sync": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", + "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", + "requires": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "workbox-broadcast-update": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", + "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-build": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz", + "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", + "requires": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.5.4", + "workbox-broadcast-update": "6.5.4", + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-google-analytics": "6.5.4", + "workbox-navigation-preload": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-range-requests": "6.5.4", + "workbox-recipes": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", + "workbox-streams": "6.5.4", + "workbox-sw": "6.5.4", + "workbox-window": "6.5.4" + }, + "dependencies": { + "@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "requires": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + } + }, + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" + }, + "source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "requires": { + "whatwg-url": "^7.0.0" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "workbox-cacheable-response": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", + "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-core": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" + }, + "workbox-expiration": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz", + "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", + "requires": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "workbox-google-analytics": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", + "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", + "requires": { + "workbox-background-sync": "6.5.4", + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "workbox-navigation-preload": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", + "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-precaching": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz", + "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", + "requires": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "workbox-range-requests": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", + "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-recipes": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz", + "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", + "requires": { + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "workbox-routing": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-strategies": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-streams": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz", + "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", + "requires": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4" + } + }, + "workbox-sw": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz", + "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" + }, + "workbox-window": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz", + "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", + "requires": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.5.4" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "dev": true, + "requires": {} + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..24a31af --- /dev/null +++ b/package.json @@ -0,0 +1,53 @@ +{ + "name": "profectus", + "version": "0.5.2", + "private": true, + "scripts": { + "start": "vite", + "dev": "vite", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview", + "test": "vitest run", + "testw": "vitest", + "serve": "vite preview --host" + }, + "dependencies": { + "@fontsource/material-icons": "^4.5.4", + "@fontsource/roboto-mono": "^4.5.8", + "@pixi/app": "~6.3.2", + "@pixi/core": "~6.3.2", + "@pixi/particle-emitter": "^5.0.4", + "@pixi/ticker": "~6.3.2", + "@vitejs/plugin-vue": "^2.3.3", + "@vitejs/plugin-vue-jsx": "^1.3.10", + "is-plain-object": "^5.0.0", + "lz-string": "^1.4.4", + "nanoevents": "^6.0.2", + "vite": "^2.9.12", + "vite-plugin-pwa": "^0.12.0", + "vite-tsconfig-paths": "^3.5.0", + "vue": "^3.2.26", + "vue-next-select": "^2.10.2", + "vue-panzoom": "^1.1.6", + "vue-textarea-autosize": "^1.1.1", + "vue-toastification": "^2.0.0-rc.1", + "vue-transition-expand": "^0.1.0", + "vuedraggable": "^4.1.0" + }, + "devDependencies": { + "@ivanv/vue-collapse-transition": "^1.0.2", + "@rushstack/eslint-patch": "^1.1.0", + "@types/lz-string": "^1.3.34", + "@vue/eslint-config-prettier": "^7.0.0", + "@vue/eslint-config-typescript": "^10.0.0", + "eslint": "^8.6.0", + "jsdom": "^20.0.0", + "prettier": "^2.5.1", + "typescript": "^4.7.4", + "vitest": "^0.17.1", + "vue-tsc": "^0.38.1" + }, + "engines": { + "node": "16.x" + } +} diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..e570640 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..028a67e Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..afa6845 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/pwa-192x192.png b/public/pwa-192x192.png new file mode 100644 index 0000000..00eaafd Binary files /dev/null and b/public/pwa-192x192.png differ diff --git a/public/pwa-512x512.png b/public/pwa-512x512.png new file mode 100644 index 0000000..1ad85e8 Binary files /dev/null and b/public/pwa-512x512.png differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..c2a49f4 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / diff --git a/replit.nix b/replit.nix new file mode 100644 index 0000000..1b59d2e --- /dev/null +++ b/replit.nix @@ -0,0 +1,7 @@ +{ pkgs }: { + deps = [ + pkgs.nodejs-16_x + pkgs.nodePackages.typescript-language-server + pkgs.nodePackages.npm + ]; +} diff --git a/saves/.placehold b/saves/.placehold new file mode 100644 index 0000000..e69de29 diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..05fa7fd --- /dev/null +++ b/src/App.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/src/components/Context.vue b/src/components/Context.vue new file mode 100644 index 0000000..33cbf2b --- /dev/null +++ b/src/components/Context.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/src/components/Game.vue b/src/components/Game.vue new file mode 100644 index 0000000..6f9bb66 --- /dev/null +++ b/src/components/Game.vue @@ -0,0 +1,92 @@ + + + + + + + diff --git a/src/components/GameOverScreen.vue b/src/components/GameOverScreen.vue new file mode 100644 index 0000000..999554d --- /dev/null +++ b/src/components/GameOverScreen.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/src/components/Info.vue b/src/components/Info.vue new file mode 100644 index 0000000..69a3545 --- /dev/null +++ b/src/components/Info.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/components/Layer.vue b/src/components/Layer.vue new file mode 100644 index 0000000..a64a255 --- /dev/null +++ b/src/components/Layer.vue @@ -0,0 +1,223 @@ + + + + + diff --git a/src/components/MarkNode.vue b/src/components/MarkNode.vue new file mode 100644 index 0000000..c730279 --- /dev/null +++ b/src/components/MarkNode.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/src/components/Modal.vue b/src/components/Modal.vue new file mode 100644 index 0000000..7a3ee19 --- /dev/null +++ b/src/components/Modal.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/src/components/NaNScreen.vue b/src/components/NaNScreen.vue new file mode 100644 index 0000000..04e6027 --- /dev/null +++ b/src/components/NaNScreen.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/src/components/Nav.vue b/src/components/Nav.vue new file mode 100644 index 0000000..d2017a8 --- /dev/null +++ b/src/components/Nav.vue @@ -0,0 +1,271 @@ + + + + + diff --git a/src/components/Node.vue b/src/components/Node.vue new file mode 100644 index 0000000..7f5b118 --- /dev/null +++ b/src/components/Node.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/components/Notif.vue b/src/components/Notif.vue new file mode 100644 index 0000000..485ca4d --- /dev/null +++ b/src/components/Notif.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/Options.vue b/src/components/Options.vue new file mode 100644 index 0000000..3e7ed4b --- /dev/null +++ b/src/components/Options.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/src/components/Profectus.vue b/src/components/Profectus.vue new file mode 100644 index 0000000..3a7700b --- /dev/null +++ b/src/components/Profectus.vue @@ -0,0 +1,195 @@ + + + diff --git a/src/components/Save.vue b/src/components/Save.vue new file mode 100644 index 0000000..c151666 --- /dev/null +++ b/src/components/Save.vue @@ -0,0 +1,204 @@ + + + + + + + diff --git a/src/components/SavesManager.vue b/src/components/SavesManager.vue new file mode 100644 index 0000000..e05ab75 --- /dev/null +++ b/src/components/SavesManager.vue @@ -0,0 +1,335 @@ + + + + + + + diff --git a/src/components/TPS.vue b/src/components/TPS.vue new file mode 100644 index 0000000..a460a09 --- /dev/null +++ b/src/components/TPS.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/src/components/common/features.css b/src/components/common/features.css new file mode 100644 index 0000000..cbed01a --- /dev/null +++ b/src/components/common/features.css @@ -0,0 +1,38 @@ +.feature:not(li), +.feature:not(li) button { + position: relative; + padding: 5px; + border-radius: var(--border-radius); + border: 2px solid rgba(0, 0, 0, 0.125); + margin: var(--feature-margin); + box-sizing: border-box; + color: var(--feature-foreground); + z-index: 0; + transition: all 0.5s, z-index 0s 0.5s; +} + +.can, +.can button { + background-color: var(--layer-color); + cursor: pointer; +} + +.can:hover, +.can:hover button { + transform: scale(1.15, 1.15); + box-shadow: 0 0 20px var(--points); + z-index: 1; + transition: all 0.5s, z-index 0s; +} + +.locked, +.locked button { + background-color: var(--locked); + cursor: not-allowed; +} + +.bought, +.bought button { + background-color: var(--bought); + cursor: default; +} diff --git a/src/components/common/fields.css b/src/components/common/fields.css new file mode 100644 index 0000000..48737e1 --- /dev/null +++ b/src/components/common/fields.css @@ -0,0 +1,13 @@ +.field { + display: flex; + position: relative; + min-height: 2em; + margin: 10px 0; + user-select: none; + justify-content: space-between; + align-items: center; +} + +.field > * { + margin: 0; +} diff --git a/src/components/common/modifiers.css b/src/components/common/modifiers.css new file mode 100644 index 0000000..fe8071e --- /dev/null +++ b/src/components/common/modifiers.css @@ -0,0 +1,16 @@ +.modifier-container { + display: flex; +} + +.modifier-container:nth-child(2n) { + background: var(--raised-background); +} + +.modifier-amount { + flex-basis: 100px; + flex-shrink: 0; +} + +.modifier-description { + flex-grow: 1; +} diff --git a/src/components/common/table.css b/src/components/common/table.css new file mode 100644 index 0000000..56d4929 --- /dev/null +++ b/src/components/common/table.css @@ -0,0 +1,91 @@ +.table { + display: flex; + flex-flow: column wrap; + justify-content: center; + align-items: center; + max-width: 100%; + margin: 0 auto; +} + +.table + .table { + margin-top: 10px; +} + +.row { + display: flex; + flex-flow: row wrap; + justify-content: center; + align-items: stretch; + max-width: 100%; + margin: 0 10px; +} + +.row > :not(.feature) { + margin: 0; + display: flex; +} + +.col { + display: flex; + flex-flow: column wrap; + justify-content: center; + align-items: center; + height: 100%; + margin: 10px 0; +} + +.row.mergeAdjacent > .feature:not(.dontMerge), +.row.mergeAdjacent > .tooltip-container > .feature:not(.dontMerge) { + margin-left: 0; + margin-right: 0; + border-radius: 0; +} + +.row.mergeAdjacent > .feature:not(.dontMerge):first-child, +.row.mergeAdjacent > .tooltip-container:first-child > .feature:not(.dontMerge) { + border-radius: var(--border-radius) 0 0 var(--border-radius); +} + +.row.mergeAdjacent > .feature:not(.dontMerge):last-child, +.row.mergeAdjacent > .tooltip-container:last-child > .feature:not(.dontMerge) { + border-radius: 0 var(--border-radius) var(--border-radius) 0; +} + +.row.mergeAdjacent > .feature:not(.dontMerge):first-child:last-child, +.row.mergeAdjacent > .tooltip-container:first-child:last-child > .feature:not(.dontMerge) { + border-radius: var(--border-radius); +} + +/* +TODO how to implement mergeAdjacent for grids? +.row.mergeAdjacent + .row.mergeAdjacent > .feature:not(.dontMerge) { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +*/ + +.col.mergeAdjacent .feature:not(.dontMerge) { + margin-top: 0; + margin-bottom: 0; + border-radius: 0; +} + +.col.mergeAdjacent .feature:not(.dontMerge):first-child { + border-radius: var(--border-radius) var(--border-radius) 0 0; +} + +.col.mergeAdjacent .feature:not(.dontMerge):last-child { + border-radius: 0 0 var(--border-radius) var(--border-radius); +} + +.col.mergeAdjacent .feature:not(.dontMerge):first-child:last-child { + border-radius: var(--border-radius); +} + +/* +TODO how to implement mergeAdjacent for grids? +.col.mergeAdjacent + .col.mergeAdjacent > .feature:not(.dontMerge) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +*/ diff --git a/src/components/fields/DangerButton.vue b/src/components/fields/DangerButton.vue new file mode 100644 index 0000000..9fb1836 --- /dev/null +++ b/src/components/fields/DangerButton.vue @@ -0,0 +1,78 @@ + + + + + + + diff --git a/src/components/fields/FeedbackButton.vue b/src/components/fields/FeedbackButton.vue new file mode 100644 index 0000000..42dcdaa --- /dev/null +++ b/src/components/fields/FeedbackButton.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/src/components/fields/Select.vue b/src/components/fields/Select.vue new file mode 100644 index 0000000..f08c40f --- /dev/null +++ b/src/components/fields/Select.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/components/fields/Slider.vue b/src/components/fields/Slider.vue new file mode 100644 index 0000000..ea6e17f --- /dev/null +++ b/src/components/fields/Slider.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/components/fields/Text.vue b/src/components/fields/Text.vue new file mode 100644 index 0000000..e7f3ab5 --- /dev/null +++ b/src/components/fields/Text.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/fields/Toggle.vue b/src/components/fields/Toggle.vue new file mode 100644 index 0000000..2dcfa6c --- /dev/null +++ b/src/components/fields/Toggle.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/src/components/layout/Collapsible.vue b/src/components/layout/Collapsible.vue new file mode 100644 index 0000000..f8700b4 --- /dev/null +++ b/src/components/layout/Collapsible.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/src/components/layout/Column.vue b/src/components/layout/Column.vue new file mode 100644 index 0000000..c9dd027 --- /dev/null +++ b/src/components/layout/Column.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/layout/Row.vue b/src/components/layout/Row.vue new file mode 100644 index 0000000..861c9ff --- /dev/null +++ b/src/components/layout/Row.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/layout/Spacer.vue b/src/components/layout/Spacer.vue new file mode 100644 index 0000000..a5cfa56 --- /dev/null +++ b/src/components/layout/Spacer.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/layout/Sticky.vue b/src/components/layout/Sticky.vue new file mode 100644 index 0000000..d761210 --- /dev/null +++ b/src/components/layout/Sticky.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/src/components/layout/VerticalRule.vue b/src/components/layout/VerticalRule.vue new file mode 100644 index 0000000..04a8adf --- /dev/null +++ b/src/components/layout/VerticalRule.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/src/components/math/Floor.vue b/src/components/math/Floor.vue new file mode 100644 index 0000000..7010c59 --- /dev/null +++ b/src/components/math/Floor.vue @@ -0,0 +1,5 @@ + diff --git a/src/components/math/Sqrt.vue b/src/components/math/Sqrt.vue new file mode 100644 index 0000000..dc8292e --- /dev/null +++ b/src/components/math/Sqrt.vue @@ -0,0 +1,6 @@ + diff --git a/src/data/Changelog.vue b/src/data/Changelog.vue new file mode 100644 index 0000000..54e53a5 --- /dev/null +++ b/src/data/Changelog.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/data/common.css b/src/data/common.css new file mode 100644 index 0000000..728c160 --- /dev/null +++ b/src/data/common.css @@ -0,0 +1,9 @@ +.modifier-toggle { + padding-right: 10px; + transform: translateY(-1px); + display: inline-block; +} + +.modifier-toggle.collapsed { + transform: translate(-5px, -5px) rotate(-90deg); +} diff --git a/src/data/common.tsx b/src/data/common.tsx new file mode 100644 index 0000000..d3eda18 --- /dev/null +++ b/src/data/common.tsx @@ -0,0 +1,348 @@ +import type { Clickable, ClickableOptions, GenericClickable } from "features/clickables/clickable"; +import { createClickable } from "features/clickables/clickable"; +import type { GenericConversion } from "features/conversion"; +import type { CoercableComponent, JSXFunction, OptionsFunc, Replace } from "features/feature"; +import { jsx, setDefault } from "features/feature"; +import { displayResource } from "features/resources/resource"; +import type { GenericTree, GenericTreeNode, TreeNode, TreeNodeOptions } from "features/trees/tree"; +import { createTreeNode } from "features/trees/tree"; +import type { Modifier } from "game/modifiers"; +import type { Persistent } from "game/persistence"; +import { DefaultValue, persistent } from "game/persistence"; +import player from "game/player"; +import type { DecimalSource } from "util/bignum"; +import Decimal, { format } from "util/bignum"; +import type { WithRequired } from "util/common"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { convertComputable, processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { renderJSX } from "util/vue"; +import type { Ref } from "vue"; +import { computed, unref } from "vue"; +import "./common.css"; + +/** An object that configures a {@link ResetButton} */ +export interface ResetButtonOptions extends ClickableOptions { + /** The conversion the button uses to calculate how much resources will be gained on click */ + conversion: GenericConversion; + /** The tree this reset button is apart of */ + tree: GenericTree; + /** The specific tree node associated with this reset button */ + treeNode: GenericTreeNode; + /** + * Text to display on low conversion amounts, describing what "resetting" is in this context. + * Defaults to "Reset for ". + */ + resetDescription?: Computable; + /** Whether or not to show how much currency would be required to make the gain amount increase. */ + showNextAt?: Computable; + /** + * The content to display on the button. + * By default, this includes the reset description, and amount of currency to be gained. + */ + display?: Computable; + /** + * Whether or not this button can currently be clicked. + * Defaults to checking the current gain amount is greater than {@link minimumGain} + */ + canClick?: Computable; + /** + * When {@link canClick} is left to its default, minimumGain is used to only enable the reset button when a sufficient amount of currency to gain is available. + */ + minimumGain?: Computable; + /** A persistent ref to track how much time has passed since the last time this tree node was reset. */ + resetTime?: Persistent; +} + +/** + * A button that is used to control a conversion. + * It will show how much can be converted currently, and can show when that amount will go up, as well as handle only being clickable when a sufficient amount of currency can be gained. + * Assumes this button is associated with a specific node on a tree, and triggers that tree's reset propagation. + */ +export type ResetButton = Replace< + Clickable, + { + resetDescription: GetComputableTypeWithDefault>; + showNextAt: GetComputableTypeWithDefault; + display: GetComputableTypeWithDefault>; + canClick: GetComputableTypeWithDefault>; + minimumGain: GetComputableTypeWithDefault; + onClick: VoidFunction; + } +>; + +/** A type that matches any valid {@link ResetButton} object. */ +export type GenericResetButton = Replace< + GenericClickable & ResetButton, + { + resetDescription: ProcessedComputable; + showNextAt: ProcessedComputable; + display: ProcessedComputable; + canClick: ProcessedComputable; + minimumGain: ProcessedComputable; + } +>; + +/** + * Lazily creates a reset button with the given options. + * @param optionsFunc A function that returns the options object for this reset button. + */ +export function createResetButton( + optionsFunc: OptionsFunc +): ResetButton { + return createClickable(() => { + const resetButton = optionsFunc(); + + processComputable(resetButton as T, "showNextAt"); + setDefault(resetButton, "showNextAt", true); + setDefault(resetButton, "minimumGain", 1); + + if (resetButton.resetDescription == null) { + resetButton.resetDescription = computed(() => + Decimal.lt(resetButton.conversion.gainResource.value, 1e3) ? "Reset for " : "" + ); + } else { + processComputable(resetButton as T, "resetDescription"); + } + + if (resetButton.display == null) { + resetButton.display = jsx(() => ( + + {unref(resetButton.resetDescription as ProcessedComputable)} + + {displayResource( + resetButton.conversion.gainResource, + Decimal.max( + unref(resetButton.conversion.actualGain), + unref(resetButton.minimumGain as ProcessedComputable) + ) + )} + {" "} + {resetButton.conversion.gainResource.displayName} + {unref(resetButton.showNextAt) ? ( +
+
+ {unref(resetButton.conversion.buyMax) ? "Next:" : "Req:"}{" "} + {displayResource( + resetButton.conversion.baseResource, + unref(resetButton.conversion.buyMax) || + Decimal.floor(unref(resetButton.conversion.actualGain)).neq(1) + ? unref(resetButton.conversion.nextAt) + : unref(resetButton.conversion.currentAt) + )}{" "} + {resetButton.conversion.baseResource.displayName} +
+ ) : null} +
+ )); + } + + if (resetButton.canClick == null) { + resetButton.canClick = computed(() => + Decimal.gte( + unref(resetButton.conversion.actualGain), + unref(resetButton.minimumGain as ProcessedComputable) + ) + ); + } + + const onClick = resetButton.onClick; + resetButton.onClick = function () { + if (!unref(resetButton.canClick)) { + return; + } + resetButton.conversion.convert(); + resetButton.tree.reset(resetButton.treeNode); + if (resetButton.resetTime) { + resetButton.resetTime.value = resetButton.resetTime[DefaultValue]; + } + onClick?.(); + }; + + return resetButton; + }) as unknown as ResetButton; +} + +/** An object that configures a {@link LayerTreeNode} */ +export interface LayerTreeNodeOptions extends TreeNodeOptions { + /** The ID of the layer this tree node is associated with */ + layerID: string; + /** The color to display this tree node as */ + color: Computable; // marking as required + /** + * The content to display in the tree node. + * Defaults to the layer's ID + */ + display?: Computable; + /** Whether or not to append the layer to the tabs list. + * If set to false, then the tree node will instead always remove all tabs to its right and then add the layer tab. + * Defaults to true. + */ + append?: Computable; +} +/** A tree node that is associated with a given layer, and which opens the layer when clicked. */ +export type LayerTreeNode = Replace< + TreeNode, + { + display: GetComputableTypeWithDefault; + append: GetComputableType; + } +>; +/** A type that matches any valid {@link LayerTreeNode} object. */ +export type GenericLayerTreeNode = Replace< + LayerTreeNode, + { + display: ProcessedComputable; + append?: ProcessedComputable; + } +>; + +/** + * Lazily creates a tree node that's associated with a specific layer, with the given options. + * @param optionsFunc A function that returns the options object for this tree node. + */ +export function createLayerTreeNode( + optionsFunc: OptionsFunc +): LayerTreeNode { + return createTreeNode(() => { + const options = optionsFunc(); + processComputable(options as T, "display"); + setDefault(options, "display", options.layerID); + processComputable(options as T, "append"); + return { + ...options, + display: options.display, + onClick: unref((options as unknown as GenericLayerTreeNode).append) + ? function () { + if (player.tabs.includes(options.layerID)) { + const index = player.tabs.lastIndexOf(options.layerID); + player.tabs.splice(index, 1); + } else { + player.tabs.push(options.layerID); + } + } + : function () { + player.tabs.splice(1, 1, options.layerID); + } + }; + }) as unknown as LayerTreeNode; +} + +/** An option object for a modifier display as a single section. **/ +export interface Section { + /** The header for this modifier. **/ + title: string; + /** A subtitle for this modifier, e.g. to explain the context for the modifier. **/ + subtitle?: string; + /** The modifier to be displaying in this section. **/ + modifier: WithRequired; + /** The base value being modified. **/ + base?: Computable; + /** The unit of measurement for the base. **/ + unit?: string; + /** The label to call the base amount. Defaults to "Base". **/ + baseText?: Computable; + /** Whether or not this section should be currently visible to the player. **/ + visible?: Computable; +} + +/** + * Takes an array of modifier "sections", and creates a JSXFunction that can render all those sections, and allow each section to be collapsed. + * Also returns a list of persistent refs that are used to control which sections are currently collapsed. + * @param sectionsFunc A function that returns the sections to display. + */ +export function createCollapsibleModifierSections( + sectionsFunc: () => Section[] +): [JSXFunction, Persistent>] { + const sections: Section[] = []; + const processed: + | { + base: ProcessedComputable[]; + baseText: ProcessedComputable[]; + visible: ProcessedComputable[]; + } + | Record = {}; + let calculated = false; + function calculateSections() { + if (!calculated) { + sections.push(...sectionsFunc()); + processed.base = sections.map(s => convertComputable(s.base)); + processed.baseText = sections.map(s => convertComputable(s.baseText)); + processed.visible = sections.map(s => convertComputable(s.visible)); + calculated = true; + } + return sections; + } + + const collapsed = persistent>({}); + const jsxFunc = jsx(() => { + const sections = calculateSections(); + + let firstVisibleSection = true; + const sectionJSX = sections.map((s, i) => { + if (unref(processed.visible[i]) === false) return null; + const header = ( +

(collapsed.value[i] = !collapsed.value[i])} + style="cursor: pointer" + > + + ▼ + + {s.title} + {s.subtitle ? ({s.subtitle}) : null} +

+ ); + + const modifiers = unref(collapsed.value[i]) ? null : ( + <> +
+ + {format(unref(processed.base[i]) ?? 1)} + {s.unit} + + + {renderJSX(unref(processed.baseText[i]) ?? "Base")} + +
+ {renderJSX(unref(s.modifier.description))} + + ); + + const hasPreviousSection = !firstVisibleSection; + firstVisibleSection = false; + + return ( + <> + {hasPreviousSection ?
: null} +
+ {header} +
+ {modifiers} +
+ Total: {format(s.modifier.apply(unref(processed.base[i]) ?? 1))} + {s.unit} +
+ + ); + }); + return <>{sectionJSX}; + }); + return [jsxFunc, collapsed]; +} + +/** + * Creates an HTML string for a span that writes some given text in a given color. + * @param textToColor The content to change the color of + * @param color The color to change the content to look like. Defaults to the current theme's accent 2 variable. + */ +export function colorText(textToColor: string, color = "var(--accent2)"): JSX.Element { + return {textToColor}; +} diff --git a/src/data/layers/prestige.tsx b/src/data/layers/prestige.tsx new file mode 100644 index 0000000..4490ded --- /dev/null +++ b/src/data/layers/prestige.tsx @@ -0,0 +1,73 @@ +/** + * @module + * @hidden + */ +import { main } from "data/projEntry"; +import { createCumulativeConversion, createPolynomialScaling } from "features/conversion"; +import { jsx } from "features/feature"; +import { createHotkey } from "features/hotkey"; +import { createReset } from "features/reset"; +import MainDisplay from "features/resources/MainDisplay.vue"; +import { createResource } from "features/resources/resource"; +import { addTooltip } from "features/tooltips/tooltip"; +import { createResourceTooltip } from "features/trees/tree"; +import { BaseLayer, createLayer } from "game/layers"; +import type { DecimalSource } from "util/bignum"; +import { render } from "util/vue"; +import { createLayerTreeNode, createResetButton } from "../common"; + +const id = "p"; +const layer = createLayer(id, function (this: BaseLayer) { + const name = "Prestige"; + const color = "#4BDC13"; + const points = createResource(0, "prestige points"); + + const conversion = createCumulativeConversion(() => ({ + scaling: createPolynomialScaling(10, 0.5), + baseResource: main.points, + gainResource: points, + roundUpCost: true + })); + + const reset = createReset(() => ({ + thingsToReset: (): Record[] => [layer] + })); + + const treeNode = createLayerTreeNode(() => ({ + layerID: id, + color, + reset + })); + addTooltip(treeNode, { + display: createResourceTooltip(points), + pinnable: true + }); + + const resetButton = createResetButton(() => ({ + conversion, + tree: main.tree, + treeNode + })); + + const hotkey = createHotkey(() => ({ + description: "Reset for prestige points", + key: "p", + onPress: resetButton.onClick + })); + + return { + name, + color, + points, + display: jsx(() => ( + <> + + {render(resetButton)} + + )), + treeNode, + hotkey + }; +}); + +export default layer; diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx new file mode 100644 index 0000000..8ee2c7b --- /dev/null +++ b/src/data/projEntry.tsx @@ -0,0 +1,103 @@ +import Spacer from "components/layout/Spacer.vue"; +import { jsx } from "features/feature"; +import { createResource, trackBest, trackOOMPS, trackTotal } from "features/resources/resource"; +import type { GenericTree } from "features/trees/tree"; +import { branchedResetPropagation, createTree } from "features/trees/tree"; +import { globalBus } from "game/events"; +import type { BaseLayer, GenericLayer } from "game/layers"; +import { createLayer } from "game/layers"; +import type { PlayerData } from "game/player"; +import player from "game/player"; +import type { DecimalSource } from "util/bignum"; +import Decimal, { format, formatTime } from "util/bignum"; +import { render } from "util/vue"; +import { computed, toRaw } from "vue"; +import prestige from "./layers/prestige"; + +/** + * @hidden + */ +export const main = createLayer("main", function (this: BaseLayer) { + const points = createResource(10); + const best = trackBest(points); + const total = trackTotal(points); + + const pointGain = computed(() => { + // eslint-disable-next-line prefer-const + let gain = new Decimal(1); + return gain; + }); + globalBus.on("update", diff => { + points.value = Decimal.add(points.value, Decimal.times(pointGain.value, diff)); + }); + const oomps = trackOOMPS(points, pointGain); + + const tree = createTree(() => ({ + nodes: [[prestige.treeNode]], + branches: [], + onReset() { + points.value = toRaw(this.resettingNode.value) === toRaw(prestige.treeNode) ? 0 : 10; + best.value = points.value; + total.value = points.value; + }, + resetPropagation: branchedResetPropagation + })) as GenericTree; + + return { + name: "Tree", + links: tree.links, + display: jsx(() => ( + <> + {player.devSpeed === 0 ?
Game Paused
: null} + {player.devSpeed && player.devSpeed !== 1 ? ( +
Dev Speed: {format(player.devSpeed)}x
+ ) : null} + {player.offlineTime ? ( +
Offline Time: {formatTime(player.offlineTime)}
+ ) : null} +
+ {Decimal.lt(points.value, "1e1000") ? You have : null} +

{format(points.value)}

+ {Decimal.lt(points.value, "1e1e6") ? points : null} +
+ {Decimal.gt(pointGain.value, 0) ?
({oomps.value})
: null} + + {render(tree)} + + )), + points, + best, + total, + oomps, + tree + }; +}); + +/** + * Given a player save data object being loaded, return a list of layers that should currently be enabled. + * If your project does not use dynamic layers, this should just return all layers. + */ +export const getInitialLayers = ( + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ + player: Partial +): Array => [main, prestige]; + +/** + * A computed ref whose value is true whenever the game is over. + */ +export const hasWon = computed(() => { + return false; +}); + +/** + * Given a player save data object being loaded with a different version, update the save data object to match the structure of the current version. + * @param oldVersion The version of the save being loaded in + * @param player The save data being loaded in + */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +export function fixOldSave( + oldVersion: string | undefined, + player: Partial + // eslint-disable-next-line @typescript-eslint/no-empty-function +): void {} +/* eslint-enable @typescript-eslint/no-unused-vars */ diff --git a/src/data/projInfo.json b/src/data/projInfo.json new file mode 100644 index 0000000..1504cba --- /dev/null +++ b/src/data/projInfo.json @@ -0,0 +1,24 @@ +{ + "title": "Profectus", + "description": "A project made in Profectus", + "id": "", + "author": "", + "discordName": "", + "discordLink": "", + + "versionNumber": "0.0", + "versionTitle": "Initial Commit", + + "allowGoBack": true, + "defaultShowSmall": false, + "defaultDecimalsShown": 2, + "useHeader": true, + "banner": null, + "logo": "", + "initialTabs": [ "main" ], + + "maxTickLength": 3600, + "offlineLimit": 1, + "enablePausing": true, + "exportEncoding": "base64" +} diff --git a/src/data/themes.ts b/src/data/themes.ts new file mode 100644 index 0000000..7a24e1b --- /dev/null +++ b/src/data/themes.ts @@ -0,0 +1,137 @@ +/** A object of all CSS variables determined by the current theme. */ +export interface ThemeVars { + "--foreground": string; + "--background": string; + "--feature-foreground": string; + "--tooltip-background": string; + "--raised-background": string; + "--points": string; + "--locked": string; + "--highlighted": string; + "--bought": string; + "--danger": string; + "--link": string; + "--outline": string; + "--accent1": string; + "--accent2": string; + "--accent3": string; + "--border-radius": string; + "--modal-border": string; + "--feature-margin": string; +} + +/** An object representing a theme the player can use to change the look of the game. */ +export interface Theme { + /** The values of the theme's CSS variables. */ + variables: ThemeVars; + /** Whether or not tabs should "float" in the center of their container. */ + floatingTabs: boolean; + /** Whether or not adjacent features should merge together - removing the margin between them, and only applying the border radius to the first and last elements in the row or column. */ + mergeAdjacent: boolean; + /** Whether or not to show a pin icon on pinned tooltips. */ + showPin: boolean; +} + +declare module "@vue/runtime-dom" { + /** Make CSS properties accept any CSS variables usually controlled by a theme. */ + // eslint-disable-next-line @typescript-eslint/no-empty-interface + interface CSSProperties extends Partial {} + + interface HTMLAttributes { + style?: StyleValue; + } +} + +const defaultTheme: Theme = { + variables: { + "--foreground": "#dfdfdf", + "--background": "#0f0f0f", + "--feature-foreground": "#0f0f0f", + "--tooltip-background": "rgba(0, 0, 0, 0.75)", + "--raised-background": "#0f0f0f", + "--points": "#ffffff", + "--locked": "#bf8f8f", + "--highlighted": "#333", + "--bought": "#77bf5f", + "--danger": "rgb(220, 53, 69)", + "--link": "#02f2f2", + "--outline": "#dfdfdf", + "--accent1": "#627a82", + "--accent2": "#658262", + "--accent3": "#7c6282", + + "--border-radius": "15px", + "--modal-border": "solid 2px var(--color)", + "--feature-margin": "0px" + }, + floatingTabs: true, + mergeAdjacent: true, + showPin: true +}; + +/** An enum of all available themes and their internal IDs. The keys are their display names. */ +export enum Themes { + Classic = "classic", + Paper = "paper", + Nordic = "nordic", + Aqua = "aqua" +} + +/** A dictionary of all available themes. */ +export default { + classic: defaultTheme, + paper: { + ...defaultTheme, + variables: { + ...defaultTheme.variables, + "--background": "#2a323d", + "--feature-foreground": "#000", + "--raised-background": "#333c4a", + "--locked": "#3a3e45", + "--bought": "#5C8A58", + "--outline": "#333c4a", + "--border-radius": "4px", + "--modal-border": "", + "--feature-margin": "5px" + }, + floatingTabs: false + } as Theme, + // Based on https://www.nordtheme.com + nordic: { + ...defaultTheme, + variables: { + ...defaultTheme.variables, + "--foreground": "#D8DEE9", + "--background": "#2E3440", + "--feature-foreground": "#000", + "--raised-background": "#3B4252", + "--points": "#E5E9F0", + "--locked": "#4c566a", + "--highlighted": "#434c5e", + "--bought": "#8FBCBB", + "--danger": "#D08770", + "--link": "#88C0D0", + "--outline": "#3B4252", + "--accent1": "#B48EAD", + "--accent2": "#A3BE8C", + "--accent3": "#EBCB8B", + "--border-radius": "4px", + "--modal-border": "solid 2px #3B4252", + "--feature-margin": "5px" + }, + floatingTabs: false + } as Theme, + aqua: { + ...defaultTheme, + variables: { + ...defaultTheme.variables, + "--foreground": "#bfdfff", + "--background": "#001f3f", + "--tooltip-background": "rgba(0, 15, 31, 0.75)", + "--raised-background": "#001f3f", + "--points": "#dfefff", + "--locked": "#c4a7b3", + "--outline": "#bfdfff" + } + } as Theme +} as Record; diff --git a/src/features/achievements/Achievement.vue b/src/features/achievements/Achievement.vue new file mode 100644 index 0000000..5b3c7a0 --- /dev/null +++ b/src/features/achievements/Achievement.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/features/achievements/achievement.tsx b/src/features/achievements/achievement.tsx new file mode 100644 index 0000000..8bebb55 --- /dev/null +++ b/src/features/achievements/achievement.tsx @@ -0,0 +1,131 @@ +import AchievementComponent from "features/achievements/Achievement.vue"; +import { + CoercableComponent, + Component, + GatherProps, + getUniqueID, + OptionsFunc, + Replace, + setDefault, + StyleValue, + Visibility +} from "features/feature"; +import "game/notifications"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import player from "game/player"; +import settings from "game/settings"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { coerceComponent } from "util/vue"; +import { unref, watchEffect } from "vue"; +import { useToast } from "vue-toastification"; + +const toast = useToast(); + +export const AchievementType = Symbol("Achievement"); + +export interface AchievementOptions { + visibility?: Computable; + shouldEarn?: () => boolean; + display?: Computable; + mark?: Computable; + image?: Computable; + style?: Computable; + classes?: Computable>; + onComplete?: VoidFunction; +} + +export interface BaseAchievement { + id: string; + earned: Persistent; + complete: VoidFunction; + type: typeof AchievementType; + [Component]: typeof AchievementComponent; + [GatherProps]: () => Record; +} + +export type Achievement = Replace< + T & BaseAchievement, + { + visibility: GetComputableTypeWithDefault; + display: GetComputableType; + mark: GetComputableType; + image: GetComputableType; + style: GetComputableType; + classes: GetComputableType; + } +>; + +export type GenericAchievement = Replace< + Achievement, + { + visibility: ProcessedComputable; + } +>; + +export function createAchievement( + optionsFunc?: OptionsFunc +): Achievement { + const earned = persistent(false); + return createLazyProxy(() => { + const achievement = optionsFunc?.() ?? ({} as ReturnType>); + achievement.id = getUniqueID("achievement-"); + achievement.type = AchievementType; + achievement[Component] = AchievementComponent; + + achievement.earned = earned; + achievement.complete = function () { + earned.value = true; + }; + + processComputable(achievement as T, "visibility"); + setDefault(achievement, "visibility", Visibility.Visible); + processComputable(achievement as T, "display"); + processComputable(achievement as T, "mark"); + processComputable(achievement as T, "image"); + processComputable(achievement as T, "style"); + processComputable(achievement as T, "classes"); + + achievement[GatherProps] = function (this: GenericAchievement) { + const { visibility, display, earned, image, style, classes, mark, id } = this; + return { visibility, display, earned, image, style: unref(style), classes, mark, id }; + }; + + if (achievement.shouldEarn) { + const genericAchievement = achievement as GenericAchievement; + watchEffect(() => { + if (settings.active !== player.id) return; + if ( + !genericAchievement.earned.value && + unref(genericAchievement.visibility) === Visibility.Visible && + genericAchievement.shouldEarn?.() + ) { + genericAchievement.earned.value = true; + genericAchievement.onComplete?.(); + if (genericAchievement.display) { + const Display = coerceComponent(unref(genericAchievement.display)); + toast.info( +
+

Achievement earned!

+
+ {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */} + {/* @ts-ignore */} + +
+
+ ); + } + } + }); + } + + return achievement as unknown as Achievement; + }); +} diff --git a/src/features/bars/Bar.vue b/src/features/bars/Bar.vue new file mode 100644 index 0000000..df140c0 --- /dev/null +++ b/src/features/bars/Bar.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/src/features/bars/bar.ts b/src/features/bars/bar.ts new file mode 100644 index 0000000..4d15f18 --- /dev/null +++ b/src/features/bars/bar.ts @@ -0,0 +1,128 @@ +import BarComponent from "features/bars/Bar.vue"; +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; +import type { DecimalSource } from "util/bignum"; +import { Direction } from "util/common"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { unref } from "vue"; + +export const BarType = Symbol("Bar"); + +export interface BarOptions { + visibility?: Computable; + width: Computable; + height: Computable; + direction: Computable; + style?: Computable; + classes?: Computable>; + borderStyle?: Computable; + baseStyle?: Computable; + textStyle?: Computable; + fillStyle?: Computable; + progress: Computable; + display?: Computable; + mark?: Computable; +} + +export interface BaseBar { + id: string; + type: typeof BarType; + [Component]: typeof BarComponent; + [GatherProps]: () => Record; +} + +export type Bar = Replace< + T & BaseBar, + { + visibility: GetComputableTypeWithDefault; + width: GetComputableType; + height: GetComputableType; + direction: GetComputableType; + style: GetComputableType; + classes: GetComputableType; + borderStyle: GetComputableType; + baseStyle: GetComputableType; + textStyle: GetComputableType; + fillStyle: GetComputableType; + progress: GetComputableType; + display: GetComputableType; + mark: GetComputableType; + } +>; + +export type GenericBar = Replace< + Bar, + { + visibility: ProcessedComputable; + } +>; + +export function createBar( + optionsFunc: OptionsFunc +): Bar { + return createLazyProxy(() => { + const bar = optionsFunc(); + bar.id = getUniqueID("bar-"); + bar.type = BarType; + bar[Component] = BarComponent; + + processComputable(bar as T, "visibility"); + setDefault(bar, "visibility", Visibility.Visible); + processComputable(bar as T, "width"); + processComputable(bar as T, "height"); + processComputable(bar as T, "direction"); + processComputable(bar as T, "style"); + processComputable(bar as T, "classes"); + processComputable(bar as T, "borderStyle"); + processComputable(bar as T, "baseStyle"); + processComputable(bar as T, "textStyle"); + processComputable(bar as T, "fillStyle"); + processComputable(bar as T, "progress"); + processComputable(bar as T, "display"); + processComputable(bar as T, "mark"); + + bar[GatherProps] = function (this: GenericBar) { + const { + progress, + width, + height, + direction, + display, + visibility, + style, + classes, + borderStyle, + textStyle, + baseStyle, + fillStyle, + mark, + id + } = this; + return { + progress, + width, + height, + direction, + display, + visibility, + style: unref(style), + classes, + borderStyle, + textStyle, + baseStyle, + fillStyle, + mark, + id + }; + }; + + return bar as unknown as Bar; + }); +} diff --git a/src/features/boards/Board.vue b/src/features/boards/Board.vue new file mode 100644 index 0000000..90f4e79 --- /dev/null +++ b/src/features/boards/Board.vue @@ -0,0 +1,253 @@ + + + + + diff --git a/src/features/boards/BoardLink.vue b/src/features/boards/BoardLink.vue new file mode 100644 index 0000000..cb61914 --- /dev/null +++ b/src/features/boards/BoardLink.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/src/features/boards/BoardNode.vue b/src/features/boards/BoardNode.vue new file mode 100644 index 0000000..e46fb32 --- /dev/null +++ b/src/features/boards/BoardNode.vue @@ -0,0 +1,365 @@ + + + + + + + diff --git a/src/features/boards/board.ts b/src/features/boards/board.ts new file mode 100644 index 0000000..4743370 --- /dev/null +++ b/src/features/boards/board.ts @@ -0,0 +1,367 @@ +import BoardComponent from "features/boards/Board.vue"; +import type { OptionsFunc, Replace, StyleValue } from "features/feature"; +import { + Component, + findFeatures, + GatherProps, + getUniqueID, + setDefault, + Visibility +} from "features/feature"; +import { globalBus } from "game/events"; +import type { Persistent, State } from "game/persistence"; +import { persistent } from "game/persistence"; +import type { Unsubscribe } from "nanoevents"; +import { isFunction } from "util/common"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { computed, Ref, unref } from "vue"; +import type { Link } from "../links/links"; + +export const BoardType = Symbol("Board"); + +export type NodeComputable = Computable | ((node: BoardNode) => T); + +export enum ProgressDisplay { + Outline = "Outline", + Fill = "Fill" +} + +export enum Shape { + Circle = "Circle", + Diamond = "Triangle" +} + +export interface BoardNode { + id: number; + position: { + x: number; + y: number; + }; + type: string; + state?: State; + pinned?: boolean; +} + +export interface BoardNodeLink extends Omit { + startNode: BoardNode; + endNode: BoardNode; + pulsing?: boolean; +} + +export interface NodeLabel { + text: string; + color?: string; + pulsing?: boolean; +} + +export type BoardData = { + nodes: BoardNode[]; + selectedNode: number | null; + selectedAction: string | null; +}; + +export interface NodeTypeOptions { + title: NodeComputable; + label?: NodeComputable; + size: NodeComputable; + draggable?: NodeComputable; + shape: NodeComputable; + canAccept?: boolean | Ref | ((node: BoardNode, otherNode: BoardNode) => boolean); + progress?: NodeComputable; + progressDisplay?: NodeComputable; + progressColor?: NodeComputable; + fillColor?: NodeComputable; + outlineColor?: NodeComputable; + titleColor?: NodeComputable; + actions?: BoardNodeActionOptions[]; + actionDistance?: NodeComputable; + onClick?: (node: BoardNode) => void; + onDrop?: (node: BoardNode, otherNode: BoardNode) => void; + update?: (node: BoardNode, diff: number) => void; +} + +export interface BaseNodeType { + nodes: Ref; +} + +export type NodeType = Replace< + T & BaseNodeType, + { + title: GetComputableType; + label: GetComputableType; + size: GetComputableTypeWithDefault; + draggable: GetComputableTypeWithDefault; + shape: GetComputableTypeWithDefault; + canAccept: GetComputableTypeWithDefault; + progress: GetComputableType; + progressDisplay: GetComputableTypeWithDefault; + progressColor: GetComputableTypeWithDefault; + fillColor: GetComputableType; + outlineColor: GetComputableType; + titleColor: GetComputableType; + actions?: GenericBoardNodeAction[]; + actionDistance: GetComputableTypeWithDefault; + } +>; + +export type GenericNodeType = Replace< + NodeType, + { + size: NodeComputable; + draggable: NodeComputable; + shape: NodeComputable; + canAccept: NodeComputable; + progressDisplay: NodeComputable; + progressColor: NodeComputable; + actionDistance: NodeComputable; + } +>; + +export interface BoardNodeActionOptions { + id: string; + visibility?: NodeComputable; + icon: NodeComputable; + fillColor?: NodeComputable; + tooltip: NodeComputable; + links?: NodeComputable; + onClick: (node: BoardNode) => boolean | undefined; +} + +export interface BaseBoardNodeAction { + links?: Ref; +} + +export type BoardNodeAction = Replace< + T & BaseBoardNodeAction, + { + visibility: GetComputableTypeWithDefault; + icon: GetComputableType; + fillColor: GetComputableType; + tooltip: GetComputableType; + links: GetComputableType; + } +>; + +export type GenericBoardNodeAction = Replace< + BoardNodeAction, + { + visibility: NodeComputable; + } +>; + +export interface BoardOptions { + visibility?: Computable; + height?: Computable; + width?: Computable; + classes?: Computable>; + style?: Computable; + startNodes: () => Omit[]; + types: Record; +} + +export interface BaseBoard extends Persistent { + id: string; + links: Ref; + nodes: Ref; + selectedNode: Ref; + selectedAction: Ref; + type: typeof BoardType; + [Component]: typeof BoardComponent; + [GatherProps]: () => Record; +} + +export type Board = Replace< + T & BaseBoard, + { + visibility: GetComputableTypeWithDefault; + types: Record; + height: GetComputableType; + width: GetComputableType; + classes: GetComputableType; + style: GetComputableType; + } +>; + +export type GenericBoard = Replace< + Board, + { + visibility: ProcessedComputable; + } +>; + +export function createBoard( + optionsFunc: OptionsFunc +): Board { + return createLazyProxy( + persistent => { + const board = Object.assign(persistent, optionsFunc()); + board.id = getUniqueID("board-"); + board.type = BoardType; + board[Component] = BoardComponent; + + board.nodes = computed(() => processedBoard[PersistentState].value.nodes); + board.selectedNode = computed( + () => + processedBoard.nodes.value.find( + node => node.id === board[PersistentState].value.selectedNode + ) || null + ); + board.selectedAction = computed(() => { + const selectedNode = processedBoard.selectedNode.value; + if (selectedNode == null) { + return null; + } + const type = processedBoard.types[selectedNode.type]; + if (type.actions == null) { + return null; + } + return ( + type.actions.find( + action => action.id === processedBoard[PersistentState].value.selectedAction + ) || null + ); + }); + board.links = computed(() => { + if (processedBoard.selectedAction.value == null) { + return null; + } + if ( + processedBoard.selectedAction.value.links && + processedBoard.selectedNode.value + ) { + return getNodeProperty( + processedBoard.selectedAction.value.links, + processedBoard.selectedNode.value + ); + } + return null; + }); + processComputable(board as T, "visibility"); + setDefault(board, "visibility", Visibility.Visible); + processComputable(board as T, "width"); + setDefault(board, "width", "100%"); + processComputable(board as T, "height"); + setDefault(board, "height", "400px"); + processComputable(board as T, "classes"); + processComputable(board as T, "style"); + + for (const type in board.types) { + const nodeType: NodeTypeOptions & Partial = board.types[type]; + + processComputable(nodeType as NodeTypeOptions, "title"); + processComputable(nodeType as NodeTypeOptions, "label"); + processComputable(nodeType as NodeTypeOptions, "size"); + setDefault(nodeType, "size", 50); + processComputable(nodeType as NodeTypeOptions, "draggable"); + setDefault(nodeType, "draggable", false); + processComputable(nodeType as NodeTypeOptions, "shape"); + setDefault(nodeType, "shape", Shape.Circle); + processComputable(nodeType as NodeTypeOptions, "canAccept"); + setDefault(nodeType, "canAccept", false); + processComputable(nodeType as NodeTypeOptions, "progress"); + processComputable(nodeType as NodeTypeOptions, "progressDisplay"); + setDefault(nodeType, "progressDisplay", ProgressDisplay.Fill); + processComputable(nodeType as NodeTypeOptions, "progressColor"); + setDefault(nodeType, "progressColor", "none"); + processComputable(nodeType as NodeTypeOptions, "fillColor"); + processComputable(nodeType as NodeTypeOptions, "outlineColor"); + processComputable(nodeType as NodeTypeOptions, "titleColor"); + processComputable(nodeType as NodeTypeOptions, "actionDistance"); + setDefault(nodeType, "actionDistance", Math.PI / 6); + nodeType.nodes = computed(() => + board[PersistentState].value.nodes.filter(node => node.type === type) + ); + setDefault(nodeType, "onClick", function (node: BoardNode) { + board[PersistentState].value.selectedNode = node.id; + }); + + if (nodeType.actions) { + for (const action of nodeType.actions) { + processComputable(action, "visibility"); + setDefault(action, "visibility", Visibility.Visible); + processComputable(action, "icon"); + processComputable(action, "fillColor"); + processComputable(action, "tooltip"); + processComputable(action, "links"); + } + } + } + + board[GatherProps] = function (this: GenericBoard) { + const { + nodes, + types, + [PersistentState]: state, + visibility, + width, + height, + style, + classes, + links, + selectedAction, + selectedNode + } = this; + return { + nodes, + types, + [PersistentState]: state, + visibility, + width, + height, + style: unref(style), + classes, + links, + selectedAction, + selectedNode + }; + }; + + // This is necessary because board.types is different from T and Board + const processedBoard = board as unknown as Board; + return processedBoard; + }, + persistent({ + nodes: [], + selectedNode: null, + selectedAction: null + }) + ); +} + +export function getNodeProperty(property: NodeComputable, node: BoardNode): T { + return isFunction>(property) ? property(node) : unref(property); +} + +export function getUniqueNodeID(board: GenericBoard): number { + let id = 0; + board.nodes.value.forEach(node => { + if (node.id >= id) { + id = node.id + 1; + } + }); + return id; +} + +const listeners: Record = {}; +globalBus.on("addLayer", layer => { + const boards: GenericBoard[] = findFeatures(layer, BoardType) as GenericBoard[]; + listeners[layer.id] = layer.on("postUpdate", diff => { + boards.forEach(board => { + Object.values(board.types).forEach(type => + type.nodes.value.forEach(node => type.update?.(node, diff)) + ); + }); + }); +}); +globalBus.on("removeLayer", layer => { + // unsubscribe from postUpdate + listeners[layer.id]?.(); + listeners[layer.id] = undefined; +}); diff --git a/src/features/buyable.tsx b/src/features/buyable.tsx new file mode 100644 index 0000000..c2f9972 --- /dev/null +++ b/src/features/buyable.tsx @@ -0,0 +1,243 @@ +import ClickableComponent from "features/clickables/Clickable.vue"; +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, jsx, setDefault, Visibility } from "features/feature"; +import type { Resource } from "features/resources/resource"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import type { DecimalSource } from "util/bignum"; +import Decimal, { format, formatWhole } from "util/bignum"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { coerceComponent, isCoercableComponent } from "util/vue"; +import type { Ref } from "vue"; +import { computed, unref } from "vue"; + +export const BuyableType = Symbol("Buyable"); + +export type BuyableDisplay = + | CoercableComponent + | { + title?: CoercableComponent; + description?: CoercableComponent; + effectDisplay?: CoercableComponent; + showAmount?: boolean; + }; + +export interface BuyableOptions { + visibility?: Computable; + cost?: Computable; + resource?: Resource; + canPurchase?: Computable; + purchaseLimit?: Computable; + classes?: Computable>; + style?: Computable; + mark?: Computable; + small?: Computable; + display?: Computable; + onPurchase?: (cost: DecimalSource | undefined) => void; +} + +export interface BaseBuyable { + id: string; + amount: Persistent; + maxed: Ref; + canAfford: Ref; + canClick: ProcessedComputable; + onClick: VoidFunction; + purchase: VoidFunction; + type: typeof BuyableType; + [Component]: typeof ClickableComponent; + [GatherProps]: () => Record; +} + +export type Buyable = Replace< + T & BaseBuyable, + { + visibility: GetComputableTypeWithDefault; + cost: GetComputableType; + resource: GetComputableType; + canPurchase: GetComputableTypeWithDefault>; + purchaseLimit: GetComputableTypeWithDefault; + classes: GetComputableType; + style: GetComputableType; + mark: GetComputableType; + small: GetComputableType; + display: Ref; + } +>; + +export type GenericBuyable = Replace< + Buyable, + { + visibility: ProcessedComputable; + canPurchase: ProcessedComputable; + purchaseLimit: ProcessedComputable; + } +>; + +export function createBuyable( + optionsFunc: OptionsFunc +): Buyable { + const amount = persistent(0); + return createLazyProxy(() => { + const buyable = optionsFunc(); + + if (buyable.canPurchase == null && (buyable.resource == null || buyable.cost == null)) { + console.warn( + "Cannot create buyable without a canPurchase property or a resource and cost property", + buyable + ); + throw "Cannot create buyable without a canPurchase property or a resource and cost property"; + } + + buyable.id = getUniqueID("buyable-"); + buyable.type = BuyableType; + buyable[Component] = ClickableComponent; + + buyable.amount = amount; + buyable.canAfford = computed(() => { + const genericBuyable = buyable as GenericBuyable; + const cost = unref(genericBuyable.cost); + return ( + genericBuyable.resource != null && + cost != null && + Decimal.gte(genericBuyable.resource.value, cost) + ); + }); + if (buyable.canPurchase == null) { + buyable.canPurchase = computed( + () => + unref((buyable as GenericBuyable).visibility) === Visibility.Visible && + unref((buyable as GenericBuyable).canAfford) && + Decimal.lt( + (buyable as GenericBuyable).amount.value, + unref((buyable as GenericBuyable).purchaseLimit) + ) + ); + } + buyable.maxed = computed(() => + Decimal.gte( + (buyable as GenericBuyable).amount.value, + unref((buyable as GenericBuyable).purchaseLimit) + ) + ); + processComputable(buyable as T, "classes"); + const classes = buyable.classes as ProcessedComputable> | undefined; + buyable.classes = computed(() => { + const currClasses = unref(classes) || {}; + if ((buyable as GenericBuyable).maxed.value) { + currClasses.bought = true; + } + return currClasses; + }); + processComputable(buyable as T, "canPurchase"); + buyable.canClick = buyable.canPurchase as ProcessedComputable; + buyable.onClick = buyable.purchase = + buyable.onClick ?? + buyable.purchase ?? + function (this: GenericBuyable) { + const genericBuyable = buyable as GenericBuyable; + if (!unref(genericBuyable.canPurchase)) { + return; + } + const cost = unref(genericBuyable.cost); + if (genericBuyable.cost != null && genericBuyable.resource != null) { + genericBuyable.resource.value = Decimal.sub( + genericBuyable.resource.value, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + cost! + ); + genericBuyable.amount.value = Decimal.add(genericBuyable.amount.value, 1); + } + genericBuyable.onPurchase?.(cost); + }; + processComputable(buyable as T, "display"); + const display = buyable.display; + buyable.display = jsx(() => { + // TODO once processComputable types correctly, remove this "as X" + const currDisplay = unref(display) as BuyableDisplay; + if (isCoercableComponent(currDisplay)) { + const CurrDisplay = coerceComponent(currDisplay); + return ; + } + if (currDisplay != null && buyable.cost != null && buyable.resource != null) { + const genericBuyable = buyable as GenericBuyable; + const Title = coerceComponent(currDisplay.title || "", "h3"); + const Description = coerceComponent(currDisplay.description || ""); + const EffectDisplay = coerceComponent(currDisplay.effectDisplay || ""); + + return ( + + {currDisplay.title ? ( +
+ + </div> + ) : null} + {currDisplay.description ? <Description /> : null} + {currDisplay.showAmount === false ? null : ( + <div> + <br /> + {unref(genericBuyable.purchaseLimit) === Decimal.dInf ? ( + <>Amount: {formatWhole(genericBuyable.amount.value)}</> + ) : ( + <> + Amount: {formatWhole(genericBuyable.amount.value)} /{" "} + {formatWhole(unref(genericBuyable.purchaseLimit))} + </> + )} + </div> + )} + {currDisplay.effectDisplay ? ( + <div> + <br /> + Currently: <EffectDisplay /> + </div> + ) : null} + {genericBuyable.cost && !genericBuyable.maxed.value ? ( + <div> + <br /> + Cost: {format(unref(genericBuyable.cost) || 0)}{" "} + {buyable.resource.displayName} + </div> + ) : null} + </span> + ); + } + return ""; + }); + + processComputable(buyable as T, "visibility"); + setDefault(buyable, "visibility", Visibility.Visible); + processComputable(buyable as T, "cost"); + processComputable(buyable as T, "resource"); + processComputable(buyable as T, "purchaseLimit"); + setDefault(buyable, "purchaseLimit", Decimal.dInf); + processComputable(buyable as T, "style"); + processComputable(buyable as T, "mark"); + processComputable(buyable as T, "small"); + + buyable[GatherProps] = function (this: GenericBuyable) { + const { display, visibility, style, classes, onClick, canClick, small, mark, id } = + this; + return { + display, + visibility, + style: unref(style), + classes, + onClick, + canClick, + small, + mark, + id + }; + }; + + return buyable as unknown as Buyable<T>; + }); +} diff --git a/src/features/challenges/Challenge.vue b/src/features/challenges/Challenge.vue new file mode 100644 index 0000000..e387c18 --- /dev/null +++ b/src/features/challenges/Challenge.vue @@ -0,0 +1,204 @@ +<template> + <div + v-if="unref(visibility) !== Visibility.None" + :style="[ + { + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }, + notifyStyle, + unref(style) ?? {} + ]" + :class="{ + feature: true, + challenge: true, + done: unref(completed), + canStart: unref(canStart) && !unref(maxed), + maxed: unref(maxed), + ...unref(classes) + }" + > + <button + class="toggleChallenge" + @click="toggle" + :disabled="!unref(canStart) || unref(maxed)" + > + {{ buttonText }} + </button> + <component v-if="unref(comp)" :is="unref(comp)" /> + <MarkNode :mark="unref(mark)" /> + <Node :id="id" /> + </div> +</template> + +<script lang="tsx"> +import "components/common/features.css"; +import MarkNode from "components/MarkNode.vue"; +import Node from "components/Node.vue"; +import type { GenericChallenge } from "features/challenges/challenge"; +import type { StyleValue } from "features/feature"; +import { jsx, Visibility } from "features/feature"; +import { getHighNotifyStyle, getNotifyStyle } from "game/notifications"; +import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue"; +import type { Component, PropType, UnwrapRef } from "vue"; +import { computed, defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue"; + +export default defineComponent({ + props: { + active: { + type: processedPropType<boolean>(Boolean), + required: true + }, + maxed: { + type: processedPropType<boolean>(Boolean), + required: true + }, + canComplete: { + type: processedPropType<boolean>(Boolean), + required: true + }, + display: processedPropType<UnwrapRef<GenericChallenge["display"]>>( + String, + Object, + Function + ), + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + style: processedPropType<StyleValue>(String, Object, Array), + classes: processedPropType<Record<string, boolean>>(Object), + completed: { + type: processedPropType<boolean>(Boolean), + required: true + }, + canStart: { + type: processedPropType<boolean>(Boolean), + required: true + }, + mark: processedPropType<boolean | string>(Boolean, String), + id: { + type: String, + required: true + }, + toggle: { + type: Function as PropType<VoidFunction>, + required: true + } + }, + components: { + MarkNode, + Node + }, + setup(props) { + const { active, maxed, canComplete, display } = toRefs(props); + + const buttonText = computed(() => { + if (active.value) { + return canComplete.value ? "Finish" : "Exit Early"; + } + if (maxed.value) { + return "Completed"; + } + return "Start"; + }); + + const comp = shallowRef<Component | string>(""); + + const notifyStyle = computed(() => { + const currActive = unwrapRef(active); + const currCanComplete = unwrapRef(canComplete); + if (currActive) { + if (currCanComplete) { + return getHighNotifyStyle(); + } + return getNotifyStyle(); + } + return {}; + }); + + watchEffect(() => { + const currDisplay = unwrapRef(display); + if (currDisplay == null) { + comp.value = ""; + return; + } + if (isCoercableComponent(currDisplay)) { + comp.value = coerceComponent(currDisplay); + return; + } + const Title = coerceComponent(currDisplay.title || "", "h3"); + const Description = coerceComponent(currDisplay.description, "div"); + const Goal = coerceComponent(currDisplay.goal || ""); + const Reward = coerceComponent(currDisplay.reward || ""); + const EffectDisplay = coerceComponent(currDisplay.effectDisplay || ""); + comp.value = coerceComponent( + jsx(() => ( + <span> + {currDisplay.title ? ( + <div> + <Title /> + </div> + ) : null} + <Description /> + {currDisplay.goal ? ( + <div> + <br /> + Goal: <Goal /> + </div> + ) : null} + {currDisplay.reward ? ( + <div> + <br /> + Reward: <Reward /> + </div> + ) : null} + {currDisplay.effectDisplay ? ( + <div> + Currently: <EffectDisplay /> + </div> + ) : null} + </span> + )) + ); + }); + + return { + buttonText, + notifyStyle, + comp, + Visibility, + unref + }; + } +}); +</script> + +<style scoped> +.challenge { + background-color: var(--locked); + width: 300px; + min-height: 300px; + color: black; + font-size: 15px; + display: flex; + flex-flow: column; + align-items: center; +} + +.challenge.done { + background-color: var(--bought); +} + +.challenge button { + min-height: 50px; + width: 120px; + border-radius: var(--border-radius); + box-shadow: none !important; + background: transparent; +} + +.challenge.canStart button { + cursor: pointer; + background-color: var(--layer-color); +} +</style> diff --git a/src/features/challenges/challenge.tsx b/src/features/challenges/challenge.tsx new file mode 100644 index 0000000..469d34a --- /dev/null +++ b/src/features/challenges/challenge.tsx @@ -0,0 +1,307 @@ +import { isArray } from "@vue/shared"; +import Toggle from "components/fields/Toggle.vue"; +import ChallengeComponent from "features/challenges/Challenge.vue"; +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, jsx, setDefault, Visibility } from "features/feature"; +import type { GenericReset } from "features/reset"; +import type { Resource } from "features/resources/resource"; +import { globalBus } from "game/events"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import settings, { registerSettingField } from "game/settings"; +import type { DecimalSource } from "util/bignum"; +import Decimal from "util/bignum"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { Ref, WatchStopHandle } from "vue"; +import { computed, unref, watch } from "vue"; + +export const ChallengeType = Symbol("ChallengeType"); + +export interface ChallengeOptions { + visibility?: Computable<Visibility>; + canStart?: Computable<boolean>; + reset?: GenericReset; + canComplete?: Computable<boolean | DecimalSource>; + completionLimit?: Computable<DecimalSource>; + mark?: Computable<boolean | string>; + resource?: Resource; + goal?: Computable<DecimalSource>; + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + display?: Computable< + | CoercableComponent + | { + title?: CoercableComponent; + description: CoercableComponent; + goal?: CoercableComponent; + reward?: CoercableComponent; + effectDisplay?: CoercableComponent; + } + >; + onComplete?: VoidFunction; + onExit?: VoidFunction; + onEnter?: VoidFunction; +} + +export interface BaseChallenge { + id: string; + completions: Persistent<DecimalSource>; + completed: Ref<boolean>; + maxed: Ref<boolean>; + active: Persistent<boolean>; + toggle: VoidFunction; + complete: (remainInChallenge?: boolean) => void; + type: typeof ChallengeType; + [Component]: typeof ChallengeComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Challenge<T extends ChallengeOptions> = Replace< + T & BaseChallenge, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + canStart: GetComputableTypeWithDefault<T["canStart"], true>; + canComplete: GetComputableTypeWithDefault<T["canComplete"], Ref<boolean>>; + completionLimit: GetComputableTypeWithDefault<T["completionLimit"], 1>; + mark: GetComputableTypeWithDefault<T["mark"], Ref<boolean>>; + goal: GetComputableType<T["goal"]>; + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + display: GetComputableType<T["display"]>; + } +>; + +export type GenericChallenge = Replace< + Challenge<ChallengeOptions>, + { + visibility: ProcessedComputable<Visibility>; + canStart: ProcessedComputable<boolean>; + canComplete: ProcessedComputable<boolean | DecimalSource>; + completionLimit: ProcessedComputable<DecimalSource>; + mark: ProcessedComputable<boolean>; + } +>; + +export function createChallenge<T extends ChallengeOptions>( + optionsFunc: OptionsFunc<T, BaseChallenge, GenericChallenge> +): Challenge<T> { + const completions = persistent(0); + const active = persistent(false); + return createLazyProxy(() => { + const challenge = optionsFunc(); + + if ( + challenge.canComplete == null && + (challenge.resource == null || challenge.goal == null) + ) { + console.warn( + "Cannot create challenge without a canComplete property or a resource and goal property", + challenge + ); + throw "Cannot create challenge without a canComplete property or a resource and goal property"; + } + + challenge.id = getUniqueID("challenge-"); + challenge.type = ChallengeType; + challenge[Component] = ChallengeComponent; + + challenge.completions = completions; + challenge.active = active; + challenge.completed = computed(() => + Decimal.gt((challenge as GenericChallenge).completions.value, 0) + ); + challenge.maxed = computed(() => + Decimal.gte( + (challenge as GenericChallenge).completions.value, + unref((challenge as GenericChallenge).completionLimit) + ) + ); + challenge.toggle = function () { + const genericChallenge = challenge as GenericChallenge; + if (genericChallenge.active.value) { + if (unref(genericChallenge.canComplete) && !genericChallenge.maxed.value) { + let completions: boolean | DecimalSource = unref(genericChallenge.canComplete); + if (typeof completions === "boolean") { + completions = 1; + } + genericChallenge.completions.value = Decimal.min( + Decimal.add(genericChallenge.completions.value, completions), + unref(genericChallenge.completionLimit) + ); + genericChallenge.onComplete?.(); + } + genericChallenge.active.value = false; + genericChallenge.onExit?.(); + genericChallenge.reset?.reset(); + } else if ( + unref(genericChallenge.canStart) && + unref(genericChallenge.visibility) === Visibility.Visible && + !genericChallenge.maxed.value + ) { + genericChallenge.reset?.reset(); + genericChallenge.active.value = true; + genericChallenge.onEnter?.(); + } + }; + challenge.complete = function (remainInChallenge?: boolean) { + const genericChallenge = challenge as GenericChallenge; + let completions: boolean | DecimalSource = unref(genericChallenge.canComplete); + if ( + genericChallenge.active.value && + completions !== false && + (completions === true || Decimal.neq(0, completions)) && + !genericChallenge.maxed.value + ) { + if (typeof completions === "boolean") { + completions = 1; + } + genericChallenge.completions.value = Decimal.min( + Decimal.add(genericChallenge.completions.value, completions), + unref(genericChallenge.completionLimit) + ); + genericChallenge.onComplete?.(); + if (remainInChallenge !== true) { + genericChallenge.active.value = false; + genericChallenge.onExit?.(); + genericChallenge.reset?.reset(); + } + } + }; + processComputable(challenge as T, "visibility"); + setDefault(challenge, "visibility", Visibility.Visible); + const visibility = challenge.visibility as ProcessedComputable<Visibility>; + challenge.visibility = computed(() => { + if (settings.hideChallenges === true && unref(challenge.maxed)) { + return Visibility.None; + } + return unref(visibility); + }); + if (challenge.canComplete == null) { + challenge.canComplete = computed(() => { + const genericChallenge = challenge as GenericChallenge; + if ( + !genericChallenge.active.value || + genericChallenge.resource == null || + genericChallenge.goal == null + ) { + return false; + } + return Decimal.gte(genericChallenge.resource.value, unref(genericChallenge.goal)); + }); + } + if (challenge.mark == null) { + challenge.mark = computed( + () => + Decimal.gt(unref((challenge as GenericChallenge).completionLimit), 1) && + !!unref(challenge.maxed) + ); + } + + processComputable(challenge as T, "canStart"); + setDefault(challenge, "canStart", true); + processComputable(challenge as T, "canComplete"); + processComputable(challenge as T, "completionLimit"); + setDefault(challenge, "completionLimit", 1); + processComputable(challenge as T, "mark"); + processComputable(challenge as T, "goal"); + processComputable(challenge as T, "classes"); + processComputable(challenge as T, "style"); + processComputable(challenge as T, "display"); + + if (challenge.reset != null) { + globalBus.on("reset", currentReset => { + if (currentReset === challenge.reset && (challenge.active as Ref<boolean>).value) { + (challenge.toggle as VoidFunction)(); + } + }); + } + + challenge[GatherProps] = function (this: GenericChallenge) { + const { + active, + maxed, + canComplete, + display, + visibility, + style, + classes, + completed, + canStart, + mark, + id, + toggle + } = this; + return { + active, + maxed, + canComplete, + display, + visibility, + style: unref(style), + classes, + completed, + canStart, + mark, + id, + toggle + }; + }; + + return challenge as unknown as Challenge<T>; + }); +} + +export function setupAutoComplete( + challenge: GenericChallenge, + autoActive: Computable<boolean> = true, + exitOnComplete = true +): WatchStopHandle { + const isActive = typeof autoActive === "function" ? computed(autoActive) : autoActive; + return watch([challenge.canComplete, isActive], ([canComplete, isActive]) => { + if (canComplete && isActive) { + challenge.complete(!exitOnComplete); + } + }); +} + +export function createActiveChallenge( + challenges: GenericChallenge[] +): Ref<GenericChallenge | undefined> { + return computed(() => challenges.find(challenge => challenge.active.value)); +} + +export function isAnyChallengeActive( + challenges: GenericChallenge[] | Ref<GenericChallenge | undefined> +): Ref<boolean> { + if (isArray(challenges)) { + challenges = createActiveChallenge(challenges); + } + return computed(() => (challenges as Ref<GenericChallenge | undefined>).value != null); +} + +declare module "game/settings" { + interface Settings { + hideChallenges: boolean; + } +} + +globalBus.on("loadSettings", settings => { + setDefault(settings, "hideChallenges", false); +}); + +registerSettingField( + jsx(() => ( + <Toggle + title="Hide Maxed Challenges" + onUpdate:modelValue={value => (settings.hideChallenges = value)} + modelValue={settings.hideChallenges} + /> + )) +); diff --git a/src/features/clickables/Clickable.vue b/src/features/clickables/Clickable.vue new file mode 100644 index 0000000..970b2f0 --- /dev/null +++ b/src/features/clickables/Clickable.vue @@ -0,0 +1,138 @@ +<template> + <button + v-if="unref(visibility) !== Visibility.None" + :style="[ + { visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined }, + unref(style) ?? [] + ]" + @click="onClick" + @mousedown="start" + @mouseleave="stop" + @mouseup="stop" + @touchstart.passive="start" + @touchend.passive="stop" + @touchcancel.passive="stop" + :class="{ + feature: true, + clickable: true, + can: unref(canClick), + locked: !unref(canClick), + small, + ...unref(classes) + }" + > + <component v-if="unref(comp)" :is="unref(comp)" /> + <MarkNode :mark="unref(mark)" /> + <Node :id="id" /> + </button> +</template> + +<script lang="tsx"> +import "components/common/features.css"; +import MarkNode from "components/MarkNode.vue"; +import Node from "components/Node.vue"; +import type { GenericClickable } from "features/clickables/clickable"; +import type { StyleValue } from "features/feature"; +import { jsx, Visibility } from "features/feature"; +import { + coerceComponent, + isCoercableComponent, + processedPropType, + setupHoldToClick, + unwrapRef +} from "util/vue"; +import type { Component, PropType, UnwrapRef } from "vue"; +import { defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue"; + +export default defineComponent({ + props: { + display: { + type: processedPropType<UnwrapRef<GenericClickable["display"]>>( + Object, + String, + Function + ), + required: true + }, + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + style: processedPropType<StyleValue>(Object, String, Array), + classes: processedPropType<Record<string, boolean>>(Object), + onClick: Function as PropType<(e?: MouseEvent | TouchEvent) => void>, + onHold: Function as PropType<VoidFunction>, + canClick: { + type: processedPropType<boolean>(Boolean), + required: true + }, + small: Boolean, + mark: processedPropType<boolean | string>(Boolean, String), + id: { + type: String, + required: true + } + }, + components: { + Node, + MarkNode + }, + setup(props) { + const { display, onClick, onHold } = toRefs(props); + + const comp = shallowRef<Component | string>(""); + + watchEffect(() => { + const currDisplay = unwrapRef(display); + if (currDisplay == null) { + comp.value = ""; + return; + } + if (isCoercableComponent(currDisplay)) { + comp.value = coerceComponent(currDisplay); + return; + } + const Title = coerceComponent(currDisplay.title || "", "h3"); + const Description = coerceComponent(currDisplay.description, "div"); + comp.value = coerceComponent( + jsx(() => ( + <span> + {currDisplay.title ? ( + <div> + <Title /> + </div> + ) : null} + <Description /> + </span> + )) + ); + }); + + const { start, stop } = setupHoldToClick(onClick, onHold); + + return { + start, + stop, + comp, + Visibility, + unref + }; + } +}); +</script> + +<style scoped> +.clickable { + min-height: 120px; + width: 120px; + font-size: 10px; +} + +.clickable.small { + min-height: unset; +} + +.clickable > * { + pointer-events: none; +} +</style> diff --git a/src/features/clickables/clickable.ts b/src/features/clickables/clickable.ts new file mode 100644 index 0000000..b3eb7f3 --- /dev/null +++ b/src/features/clickables/clickable.ts @@ -0,0 +1,140 @@ +import ClickableComponent from "features/clickables/Clickable.vue"; +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; +import type { BaseLayer } from "game/layers"; +import type { Unsubscribe } from "nanoevents"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { computed, unref } from "vue"; + +export const ClickableType = Symbol("Clickable"); + +export interface ClickableOptions { + visibility?: Computable<Visibility>; + canClick?: Computable<boolean>; + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + mark?: Computable<boolean | string>; + display?: Computable< + | CoercableComponent + | { + title?: CoercableComponent; + description: CoercableComponent; + } + >; + small?: boolean; + onClick?: (e?: MouseEvent | TouchEvent) => void; + onHold?: VoidFunction; +} + +export interface BaseClickable { + id: string; + type: typeof ClickableType; + [Component]: typeof ClickableComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Clickable<T extends ClickableOptions> = Replace< + T & BaseClickable, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + canClick: GetComputableTypeWithDefault<T["canClick"], true>; + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + mark: GetComputableType<T["mark"]>; + display: GetComputableType<T["display"]>; + } +>; + +export type GenericClickable = Replace< + Clickable<ClickableOptions>, + { + visibility: ProcessedComputable<Visibility>; + canClick: ProcessedComputable<boolean>; + } +>; + +export function createClickable<T extends ClickableOptions>( + optionsFunc?: OptionsFunc<T, BaseClickable, GenericClickable> +): Clickable<T> { + return createLazyProxy(() => { + const clickable = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>); + clickable.id = getUniqueID("clickable-"); + clickable.type = ClickableType; + clickable[Component] = ClickableComponent; + + processComputable(clickable as T, "visibility"); + setDefault(clickable, "visibility", Visibility.Visible); + processComputable(clickable as T, "canClick"); + setDefault(clickable, "canClick", true); + processComputable(clickable as T, "classes"); + processComputable(clickable as T, "style"); + processComputable(clickable as T, "mark"); + processComputable(clickable as T, "display"); + + if (clickable.onClick) { + const onClick = clickable.onClick.bind(clickable); + clickable.onClick = function (e) { + if (unref(clickable.canClick)) { + onClick(e); + } + }; + } + if (clickable.onHold) { + const onHold = clickable.onHold.bind(clickable); + clickable.onHold = function () { + if (unref(clickable.canClick)) { + onHold(); + } + }; + } + + clickable[GatherProps] = function (this: GenericClickable) { + const { + display, + visibility, + style, + classes, + onClick, + onHold, + canClick, + small, + mark, + id + } = this; + return { + display, + visibility, + style: unref(style), + classes, + onClick, + onHold, + canClick, + small, + mark, + id + }; + }; + + return clickable as unknown as Clickable<T>; + }); +} + +export function setupAutoClick( + layer: BaseLayer, + clickable: GenericClickable, + autoActive: Computable<boolean> = true +): Unsubscribe { + const isActive = typeof autoActive === "function" ? computed(autoActive) : autoActive; + return layer.on("update", () => { + if (unref(isActive) && unref(clickable.canClick)) { + clickable.onClick?.(); + } + }); +} diff --git a/src/features/conversion.ts b/src/features/conversion.ts new file mode 100644 index 0000000..d2a47d0 --- /dev/null +++ b/src/features/conversion.ts @@ -0,0 +1,529 @@ +import type { OptionsFunc, Replace } from "features/feature"; +import { setDefault } from "features/feature"; +import type { Resource } from "features/resources/resource"; +import type { BaseLayer } from "game/layers"; +import type { Modifier } from "game/modifiers"; +import type { DecimalSource } from "util/bignum"; +import Decimal from "util/bignum"; +import type { WithRequired } from "util/common"; +import type { Computable, GetComputableTypeWithDefault, ProcessedComputable } from "util/computed"; +import { convertComputable, processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { Ref } from "vue"; +import { computed, unref } from "vue"; + +/** An object that configures a {@link Conversion}. */ +export interface ConversionOptions { + /** + * The scaling function that is used to determine the rate of conversion from one {@link features/resources/resource.Resource} to the other. + */ + scaling: ScalingFunction; + /** + * How much of the output resource the conversion can currently convert for. + * Typically this will be set for you in a conversion constructor. + */ + currentGain?: Computable<DecimalSource>; + /** + * The absolute amount the output resource will be changed by. + * Typically this will be set for you in a conversion constructor. + * This will differ from {@link currentGain} in the cases where the conversion isn't just adding the converted amount to the output resource. + */ + actualGain?: Computable<DecimalSource>; + /** + * The amount of the input resource currently being required in order to produce the {@link currentGain}. + * That is, if it went below this value then {@link currentGain} would decrease. + * Typically this will be set for you in a conversion constructor. + */ + currentAt?: Computable<DecimalSource>; + /** + * The amount of the input resource required to make {@link currentGain} increase. + * Typically this will be set for you in a conversion constructor. + */ + nextAt?: Computable<DecimalSource>; + /** + * The input {@link features/resources/resource.Resource} for this conversion. + */ + baseResource: Resource; + /** + * The output {@link features/resources/resource.Resource} for this conversion. i.e. the resource being generated. + */ + gainResource: Resource; + /** + * Whether or not to cap the amount of the output resource gained by converting at 1. + * Defaults to true. + */ + buyMax?: Computable<boolean>; + /** + * Whether or not to round up the cost to generate a given amount of the output resource. + */ + roundUpCost?: Computable<boolean>; + /** + * The function that performs the actual conversion from {@link baseResource} to {@link gainResource}. + * Typically this will be set for you in a conversion constructor. + */ + convert?: VoidFunction; + /** + * The function that spends the {@link baseResource} as part of the conversion. + * Defaults to setting the {@link baseResource} amount to 0. + */ + spend?: (amountGained: DecimalSource) => void; + /** + * A callback that happens after a conversion has been completed. + * Receives the amount gained via conversion. + * This will not be called whenever using currentGain without calling convert (e.g. passive generation) + */ + onConvert?: (amountGained: DecimalSource) => void; + /** + * An additional modifier that will be applied to the gain amounts. + * Must be reversible in order to correctly calculate {@link nextAt}. + * @see {@link game/modifiers.createSequentialModifier} if you want to apply multiple modifiers. + */ + gainModifier?: WithRequired<Modifier, "revert">; + /** + * A modifier that will be applied to the cost amounts. + * That is to say, this modifier will be applied to the amount of baseResource before going into the scaling function. + * A cost modifier of x0.5 would give gain amounts equal to the player having half the baseResource they actually have. + * Must be reversible in order to correctly calculate {@link nextAt}. + * @see {@link game/modifiers.createSequentialModifier} if you want to apply multiple modifiers. + */ + costModifier?: WithRequired<Modifier, "revert">; +} + +/** + * The properties that are added onto a processed {@link ConversionOptions} to create a {@link Conversion}. + */ +export interface BaseConversion { + /** + * The function that performs the actual conversion. + */ + convert: VoidFunction; +} + +/** An object that converts one {@link features/resources/resource.Resource} into another at a given rate. */ +export type Conversion<T extends ConversionOptions> = Replace< + T & BaseConversion, + { + currentGain: GetComputableTypeWithDefault<T["currentGain"], Ref<DecimalSource>>; + actualGain: GetComputableTypeWithDefault<T["actualGain"], Ref<DecimalSource>>; + currentAt: GetComputableTypeWithDefault<T["currentAt"], Ref<DecimalSource>>; + nextAt: GetComputableTypeWithDefault<T["nextAt"], Ref<DecimalSource>>; + buyMax: GetComputableTypeWithDefault<T["buyMax"], true>; + spend: undefined extends T["spend"] ? (amountGained: DecimalSource) => void : T["spend"]; + roundUpCost: GetComputableTypeWithDefault<T["roundUpCost"], true>; + } +>; + +/** A type that matches any valid {@link Conversion} object. */ +export type GenericConversion = Replace< + Conversion<ConversionOptions>, + { + currentGain: ProcessedComputable<DecimalSource>; + actualGain: ProcessedComputable<DecimalSource>; + currentAt: ProcessedComputable<DecimalSource>; + nextAt: ProcessedComputable<DecimalSource>; + buyMax: ProcessedComputable<boolean>; + spend: (amountGained: DecimalSource) => void; + roundUpCost: ProcessedComputable<boolean>; + } +>; + +/** + * Lazily creates a conversion with the given options. + * You typically shouldn't use this function directly. Instead use one of the other conversion constructors, which will then call this. + * @param optionsFunc Conversion options. + * @see {@link createCumulativeConversion}. + * @see {@link createIndependentConversion}. + */ +export function createConversion<T extends ConversionOptions>( + optionsFunc: OptionsFunc<T, BaseConversion, GenericConversion> +): Conversion<T> { + return createLazyProxy(() => { + const conversion = optionsFunc(); + + if (conversion.currentGain == null) { + conversion.currentGain = computed(() => { + let gain = conversion.gainModifier + ? conversion.gainModifier.apply( + conversion.scaling.currentGain(conversion as GenericConversion) + ) + : conversion.scaling.currentGain(conversion as GenericConversion); + gain = Decimal.floor(gain).max(0); + + if (!unref(conversion.buyMax)) { + gain = gain.min(1); + } + return gain; + }); + } + if (conversion.actualGain == null) { + conversion.actualGain = conversion.currentGain; + } + if (conversion.currentAt == null) { + conversion.currentAt = computed(() => { + let current = conversion.scaling.currentAt(conversion as GenericConversion); + if (conversion.roundUpCost) current = Decimal.ceil(current); + return current; + }); + } + if (conversion.nextAt == null) { + conversion.nextAt = computed(() => { + let next = conversion.scaling.nextAt(conversion as GenericConversion); + if (conversion.roundUpCost) next = Decimal.ceil(next); + return next; + }); + } + + if (conversion.convert == null) { + conversion.convert = function () { + const amountGained = unref((conversion as GenericConversion).currentGain); + conversion.gainResource.value = Decimal.add( + conversion.gainResource.value, + amountGained + ); + (conversion as GenericConversion).spend(amountGained); + conversion.onConvert?.(amountGained); + }; + } + + if (conversion.spend == null) { + conversion.spend = function () { + conversion.baseResource.value = 0; + }; + } + + processComputable(conversion as T, "currentGain"); + processComputable(conversion as T, "actualGain"); + processComputable(conversion as T, "currentAt"); + processComputable(conversion as T, "nextAt"); + processComputable(conversion as T, "buyMax"); + setDefault(conversion, "buyMax", true); + processComputable(conversion as T, "roundUpCost"); + setDefault(conversion, "roundUpCost", true); + + return conversion as unknown as Conversion<T>; + }); +} + +/** + * A collection of functions that allow a conversion to scale the amount of resources gained based on the input resource. + * This typically shouldn't be created directly. Instead use one of the scaling function constructors. + * @see {@link createLinearScaling}. + * @see {@link createPolynomialScaling}. + */ +export interface ScalingFunction { + /** + * Calculates the amount of the output resource a conversion should be able to currently produce. + * This should be based off of `conversion.baseResource.value`. + * The conversion is responsible for applying the gainModifier, so this function should be un-modified. + * It does not need to be clamped or rounded. + */ + currentGain: (conversion: GenericConversion) => DecimalSource; + /** + * Calculates the amount of the input resource that is required for the current value of `conversion.currentGain`. + * Note that `conversion.currentGain` has been modified by `conversion.gainModifier`, so you will need to revert that as appropriate. + * The conversion is responsible for rounding up the amount as appropriate. + * The returned value should not be below 0. + */ + currentAt: (conversion: GenericConversion) => DecimalSource; + /** + * Calculates the amount of the input resource that would be required for the current value of `conversion.currentGain` to increase. + * Note that `conversion.currentGain` has been modified by `conversion.gainModifier`, so you will need to revert that as appropriate. + * The conversion is responsible for rounding up the amount as appropriate. + * The returned value should not be below 0. + */ + nextAt: (conversion: GenericConversion) => DecimalSource; +} + +/** + * Creates a scaling function based off the formula `(baseResource - base) * coefficient`. + * If the baseResource value is less than base then the currentGain will be 0. + * @param base The base variable in the scaling formula. + * @param coefficient The coefficient variable in the scaling formula. + * @example + * A scaling function created via `createLinearScaling(10, 0.5)` would produce the following values: + * | Base Resource | Current Gain | + * | ------------- | ------------ | + * | 10 | 1 | + * | 12 | 2 | + * | 20 | 6 | + */ +export function createLinearScaling( + base: Computable<DecimalSource>, + coefficient: Computable<DecimalSource> +): ScalingFunction { + const processedBase = convertComputable(base); + const processedCoefficient = convertComputable(coefficient); + return { + currentGain(conversion) { + let baseAmount: DecimalSource = unref(conversion.baseResource.value); + if (conversion.costModifier) { + baseAmount = conversion.costModifier.apply(baseAmount); + } + if (Decimal.lt(baseAmount, unref(processedBase))) { + return 0; + } + + return Decimal.sub(baseAmount, unref(processedBase)) + .sub(1) + .times(unref(processedCoefficient)) + .add(1); + }, + currentAt(conversion) { + let current: DecimalSource = unref(conversion.currentGain); + if (conversion.gainModifier) { + current = conversion.gainModifier.revert(current); + } + current = Decimal.max(0, current) + .sub(1) + .div(unref(processedCoefficient)) + .add(unref(processedBase)); + if (conversion.costModifier) { + current = conversion.costModifier.revert(current); + } + return current; + }, + nextAt(conversion) { + let next: DecimalSource = Decimal.add(unref(conversion.currentGain), 1).floor(); + if (conversion.gainModifier) { + next = conversion.gainModifier.revert(next); + } + next = Decimal.max(0, next) + .sub(1) + .div(unref(processedCoefficient)) + .add(unref(processedBase)) + .max(unref(processedBase)); + if (conversion.costModifier) { + next = conversion.costModifier.revert(next); + } + return next; + } + }; +} + +/** + * Creates a scaling function based off the formula `(baseResource / base) ^ exponent`. + * If the baseResource value is less than base then the currentGain will be 0. + * @param base The base variable in the scaling formula. + * @param exponent The exponent variable in the scaling formula. + * @example + * A scaling function created via `createPolynomialScaling(10, 0.5)` would produce the following values: + * | Base Resource | Current Gain | + * | ------------- | ------------ | + * | 10 | 1 | + * | 40 | 2 | + * | 250 | 5 | + */ +export function createPolynomialScaling( + base: Computable<DecimalSource>, + exponent: Computable<DecimalSource> +): ScalingFunction { + const processedBase = convertComputable(base); + const processedExponent = convertComputable(exponent); + return { + currentGain(conversion) { + let baseAmount: DecimalSource = unref(conversion.baseResource.value); + if (conversion.costModifier) { + baseAmount = conversion.costModifier.apply(baseAmount); + } + if (Decimal.lt(baseAmount, unref(processedBase))) { + return 0; + } + + const gain = Decimal.div(baseAmount, unref(processedBase)).pow( + unref(processedExponent) + ); + + if (gain.isNan()) { + return new Decimal(0); + } + return gain; + }, + currentAt(conversion) { + let current: DecimalSource = unref(conversion.currentGain); + if (conversion.gainModifier) { + current = conversion.gainModifier.revert(current); + } + current = Decimal.max(0, current) + .root(unref(processedExponent)) + .times(unref(processedBase)); + if (conversion.costModifier) { + current = conversion.costModifier.revert(current); + } + return current; + }, + nextAt(conversion) { + let next: DecimalSource = Decimal.add(unref(conversion.currentGain), 1).floor(); + if (conversion.gainModifier) { + next = conversion.gainModifier.revert(next); + } + next = Decimal.max(0, next) + .root(unref(processedExponent)) + .times(unref(processedBase)) + .max(unref(processedBase)); + if (conversion.costModifier) { + next = conversion.costModifier.revert(next); + } + return next; + } + }; +} + +/** + * Creates a conversion that simply adds to the gainResource amount upon converting. + * This is similar to the behavior of "normal" layers in The Modding Tree. + * This is equivalent to just calling createConversion directly. + * @param optionsFunc Conversion options. + */ +export function createCumulativeConversion<S extends ConversionOptions>( + optionsFunc: OptionsFunc<S, BaseConversion, GenericConversion> +): Conversion<S> { + return createConversion(optionsFunc); +} + +/** + * Creates a conversion that will replace the gainResource amount with the new amount upon converting. + * This is similar to the behavior of "static" layers in The Modding Tree. + * @param optionsFunc Converison options. + */ +export function createIndependentConversion<S extends ConversionOptions>( + optionsFunc: OptionsFunc<S, BaseConversion, GenericConversion> +): Conversion<S> { + return createConversion(() => { + const conversion: S = optionsFunc(); + + setDefault(conversion, "buyMax", false); + + if (conversion.currentGain == null) { + conversion.currentGain = computed(() => { + let gain = conversion.gainModifier + ? conversion.gainModifier.apply( + conversion.scaling.currentGain(conversion as GenericConversion) + ) + : conversion.scaling.currentGain(conversion as GenericConversion); + gain = Decimal.floor(gain).max(conversion.gainResource.value); + + if (!unref(conversion.buyMax)) { + gain = gain.min(Decimal.add(conversion.gainResource.value, 1)); + } + return gain; + }); + } + if (conversion.actualGain == null) { + conversion.actualGain = computed(() => { + let gain = Decimal.sub( + Decimal.floor(conversion.scaling.currentGain(conversion as GenericConversion)), + conversion.gainResource.value + ).max(0); + + if (!unref(conversion.buyMax)) { + gain = gain.min(1); + } + return gain; + }); + } + setDefault(conversion, "convert", function () { + const amountGained = unref((conversion as GenericConversion).actualGain); + conversion.gainResource.value = conversion.gainModifier + ? conversion.gainModifier.apply( + unref((conversion as GenericConversion).currentGain) + ) + : unref((conversion as GenericConversion).currentGain); + (conversion as GenericConversion).spend(amountGained); + conversion.onConvert?.(amountGained); + }); + + return conversion; + }) as Conversion<S>; +} + +/** + * This will automatically increase the value of conversion.gainResource without lowering the value of the input resource. + * It will by default perform 100% of a conversion's currentGain per second. + * If you use a ref for the rate you can set it's value to 0 when passive generation should be disabled. + * @param layer The layer this passive generation will be associated with. Typically `this` when calling this function from inside a layer's options function. + * @param conversion The conversion that will determine how much generation there is. + * @param rate A multiplier to multiply against the conversion's currentGain. + * @param cap A value that should not be passed via passive generation. If null, no cap is applied. + */ +export function setupPassiveGeneration( + layer: BaseLayer, + conversion: GenericConversion, + rate: Computable<DecimalSource> = 1, + cap: Computable<DecimalSource | null> = null +): void { + const processedRate = convertComputable(rate); + const processedCap = convertComputable(cap); + layer.on("preUpdate", diff => { + const currRate = unref(processedRate); + if (Decimal.neq(currRate, 0)) { + conversion.gainResource.value = Decimal.add( + conversion.gainResource.value, + Decimal.times(currRate, diff).times(Decimal.ceil(unref(conversion.actualGain))) + ).min(unref(processedCap) ?? Decimal.dInf); + } + }); +} + +/** + * Given a value, this function finds the amount above a certain value and raises it to a power. + * If the power is <1, this will effectively make the value scale slower after the cap. + * @param value The raw value. + * @param cap The value after which the softcap should be applied. + * @param power The power to raise value above the cap to. + * @example + * A softcap added via `addSoftcap(scaling, 100, 0.5)` would produce the following values: + * | Raw Value | Softcapped Value | + * | --------- | ---------------- | + * | 1 | 1 | + * | 100 | 100 | + * | 125 | 105 | + * | 200 | 110 | + */ +export function softcap( + value: DecimalSource, + cap: DecimalSource, + power: DecimalSource = 0.5 +): DecimalSource { + if (Decimal.lte(value, cap)) { + return value; + } else { + return Decimal.pow(value, power).times(Decimal.pow(cap, Decimal.sub(1, power))); + } +} + +/** + * Creates a scaling function based off an existing scaling function, with a softcap applied to it. + * The softcap will take any value above a certain value and raise it to a power. + * If the power is <1, this will effectively make the value scale slower after the cap. + * @param scaling The raw scaling function. + * @param cap The value after which the softcap should be applied. + * @param power The power to raise value about the cap to. + * @see {@link softcap}. + */ +export function addSoftcap( + scaling: ScalingFunction, + cap: ProcessedComputable<DecimalSource>, + power: ProcessedComputable<DecimalSource> = 0.5 +): ScalingFunction { + return { + ...scaling, + currentGain: conversion => + softcap(scaling.currentGain(conversion), unref(cap), unref(power)) + }; +} + +/** + * Creates a scaling function off an existing function, with a hardcap applied to it. + * The harcap will ensure that the currentGain will stop at a given cap. + * @param scaling The raw scaling function. + * @param cap The maximum value the scaling function can output. + */ +export function addHardcap( + scaling: ScalingFunction, + cap: ProcessedComputable<DecimalSource> +): ScalingFunction { + return { + ...scaling, + currentGain: conversion => Decimal.min(scaling.currentGain(conversion), unref(cap)) + }; +} diff --git a/src/features/feature.ts b/src/features/feature.ts new file mode 100644 index 0000000..ae14e29 --- /dev/null +++ b/src/features/feature.ts @@ -0,0 +1,146 @@ +import Decimal from "util/bignum"; +import { DoNotCache } from "util/computed"; +import type { CSSProperties, DefineComponent } from "vue"; +import { isRef } from "vue"; + +/** + * A symbol to use as a key for a vue component a feature can be rendered with + * @see {@link util/vue.VueFeature} + */ +export const Component = Symbol("Component"); +/** + * A symbol to use as a key for a prop gathering function that a feature can use to send to its component + * @see {@link util/vue.VueFeature} + */ +export const GatherProps = Symbol("GatherProps"); + +/** + * A type referring to a function that returns JSX and is marked that it shouldn't be wrapped in a ComputedRef + * @see {@link jsx} + */ +export type JSXFunction = (() => JSX.Element) & { [DoNotCache]: true }; +/** + * Any value that can be coerced into (or is) a vue component + */ +export type CoercableComponent = string | DefineComponent | JSXFunction; +/** + * Any value that can be passed into an HTML element's style attribute. + * Note that Profectus uses its own StyleValue and CSSProperties that are extended, + * in order to have additional properties added to them, such as variable CSS variables. + */ +export type StyleValue = string | CSSProperties | Array<string | CSSProperties>; + +/** A type that refers to any vue component */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type GenericComponent = DefineComponent<any, any, any>; + +/** Utility type that is S, with any properties from T that aren't already present in S */ +export type Replace<T, S> = S & Omit<T, keyof S>; + +/** + * Utility function for a function that returns an object of a given type, + * with "this" bound to what the type will eventually be processed into. + * Intended for making lazily evaluated objects. + */ +export type OptionsFunc<T, R = Record<string, unknown>, S = R> = () => T & + Partial<R> & + ThisType<T & S>; + +let id = 0; +/** + * Gets a unique ID to give to each feature, used for any sort of system that needs to identify + * elements in the DOM rather than references to the feature itself. (For example, branches) + * IDs are guaranteed unique, but _NOT_ persistent - they likely will change between updates. + * @param prefix A string to prepend to the id to make it more readable in the inspector tools + */ +export function getUniqueID(prefix = "feature-"): string { + return prefix + id++; +} + +/** Enum for what the visibility of a feature or component should be */ +export enum Visibility { + /** The feature or component should be visible */ + Visible, + /** The feature or component should not appear but still take up space */ + Hidden, + /** The feature or component should not appear not take up space */ + None +} + +/** + * Takes a function and marks it as JSX so it won't get auto-wrapped into a ComputedRef. + * The function may also return empty string as empty JSX tags cause issues. + */ +export function jsx(func: () => JSX.Element | ""): JSXFunction { + (func as Partial<JSXFunction>)[DoNotCache] = true; + return func as JSXFunction; +} + +/** Utility function to convert a boolean value into a Visbility value */ +export function showIf(condition: boolean, otherwise = Visibility.None): Visibility { + return condition ? Visibility.Visible : otherwise; +} + +/** Utility function to set a property on an object if and only if it doesn't already exist */ +export function setDefault<T, K extends keyof T>( + object: T, + key: K, + value: T[K] +): asserts object is Exclude<T, K> & Required<Pick<T, K>> { + if (object[key] === undefined && value != undefined) { + object[key] = value; + } +} + +/** + * Traverses an object and returns all features of the given type(s) + * @param obj The object to traverse + * @param types The feature types that will be searched for + */ +export function findFeatures(obj: Record<string, unknown>, ...types: symbol[]): unknown[] { + const objects: unknown[] = []; + const handleObject = (obj: Record<string, unknown>) => { + Object.keys(obj).forEach(key => { + const value = obj[key]; + if (value && typeof value === "object") { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (types.includes((value as Record<string, any>).type)) { + objects.push(value); + } else if (!(value instanceof Decimal) && !isRef(value)) { + handleObject(value as Record<string, unknown>); + } + } + }); + }; + handleObject(obj); + return objects; +} + +/** + * Traverses an object and returns all features that are _not_ any of the given types. + * Features are any object with a "type" property that has a symbol value. + * @param obj The object to traverse + * @param types The feature types that will be skipped over + */ +export function excludeFeatures(obj: Record<string, unknown>, ...types: symbol[]): unknown[] { + const objects: unknown[] = []; + const handleObject = (obj: Record<string, unknown>) => { + Object.keys(obj).forEach(key => { + const value = obj[key]; + if (value && typeof value === "object") { + if ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + typeof (value as Record<string, any>).type == "symbol" && + // eslint-disable-next-line @typescript-eslint/no-explicit-any + !types.includes((value as Record<string, any>).type) + ) { + objects.push(value); + } else if (!(value instanceof Decimal) && !isRef(value)) { + handleObject(value as Record<string, unknown>); + } + } + }); + }; + handleObject(obj); + return objects; +} diff --git a/src/features/grids/Grid.vue b/src/features/grids/Grid.vue new file mode 100644 index 0000000..729d5a5 --- /dev/null +++ b/src/features/grids/Grid.vue @@ -0,0 +1,60 @@ +<template> + <div + v-if="unref(visibility) !== Visibility.None" + :style="{ + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }" + class="table" + > + <div v-for="row in unref(rows)" class="row" :class="{ mergeAdjacent }" :key="row"> + <GridCell + v-for="col in unref(cols)" + :key="col" + v-bind="gatherCellProps(unref(cells)[row * 100 + col])" + /> + </div> + </div> +</template> + +<script lang="ts"> +import "components/common/table.css"; +import themes from "data/themes"; +import { Visibility } from "features/feature"; +import type { GridCell } from "features/grids/grid"; +import settings from "game/settings"; +import { processedPropType } from "util/vue"; +import { computed, defineComponent, unref } from "vue"; +import GridCellVue from "./GridCell.vue"; + +export default defineComponent({ + props: { + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + rows: { + type: processedPropType<number>(Number), + required: true + }, + cols: { + type: processedPropType<number>(Number), + required: true + }, + cells: { + type: processedPropType<Record<string, GridCell>>(Object), + required: true + } + }, + components: { GridCell: GridCellVue }, + setup() { + const mergeAdjacent = computed(() => themes[settings.theme].mergeAdjacent); + + function gatherCellProps(cell: GridCell) { + const { visibility, onClick, onHold, display, title, style, canClick, id } = cell; + return { visibility, onClick, onHold, display, title, style, canClick, id }; + } + + return { unref, gatherCellProps, Visibility, mergeAdjacent }; + } +}); +</script> diff --git a/src/features/grids/GridCell.vue b/src/features/grids/GridCell.vue new file mode 100644 index 0000000..c9bdbe6 --- /dev/null +++ b/src/features/grids/GridCell.vue @@ -0,0 +1,96 @@ +<template> + <button + v-if="unref(visibility) !== Visibility.None" + :class="{ feature: true, tile: true, can: unref(canClick), locked: !unref(canClick) }" + :style="[ + { + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }, + unref(style) ?? {} + ]" + @click="onClick" + @mousedown="start" + @mouseleave="stop" + @mouseup="stop" + @touchstart.passive="start" + @touchend.passive="stop" + @touchcancel.passive="stop" + > + <div v-if="title"><component :is="titleComponent" /></div> + <component :is="component" style="white-space: pre-line" /> + <Node :id="id" /> + </button> +</template> + +<script lang="ts"> +import "components/common/features.css"; +import Node from "components/Node.vue"; +import type { CoercableComponent, StyleValue } from "features/feature"; +import { Visibility } from "features/feature"; +import { + computeComponent, + computeOptionalComponent, + processedPropType, + setupHoldToClick +} from "util/vue"; +import type { PropType } from "vue"; +import { defineComponent, toRefs, unref } from "vue"; + +export default defineComponent({ + props: { + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + onClick: Function as PropType<(e?: MouseEvent | TouchEvent) => void>, + onHold: Function as PropType<VoidFunction>, + display: { + type: processedPropType<CoercableComponent>(Object, String, Function), + required: true + }, + title: processedPropType<CoercableComponent>(Object, String, Function), + style: processedPropType<StyleValue>(String, Object, Array), + canClick: { + type: processedPropType<boolean>(Boolean), + required: true + }, + id: { + type: String, + required: true + } + }, + components: { + Node + }, + setup(props) { + const { onClick, onHold, title, display } = toRefs(props); + + const { start, stop } = setupHoldToClick(onClick, onHold); + + const titleComponent = computeOptionalComponent(title); + const component = computeComponent(display); + + return { + start, + stop, + titleComponent, + component, + Visibility, + unref + }; + } +}); +</script> + +<style scoped> +.tile { + min-height: 80px; + width: 80px; + font-size: 10px; + background-color: var(--layer-color); +} + +.tile > * { + pointer-events: none; +} +</style> diff --git a/src/features/grids/grid.ts b/src/features/grids/grid.ts new file mode 100644 index 0000000..05890a7 --- /dev/null +++ b/src/features/grids/grid.ts @@ -0,0 +1,302 @@ +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; +import GridComponent from "features/grids/Grid.vue"; +import type { Persistent, State } from "game/persistence"; +import { persistent } from "game/persistence"; +import { isFunction } from "util/common"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { Ref } from "vue"; +import { computed, unref } from "vue"; + +export const GridType = Symbol("Grid"); + +export type CellComputable<T> = Computable<T> | ((id: string | number, state: State) => T); + +function createGridProxy(grid: GenericGrid): Record<string | number, GridCell> { + return new Proxy({}, getGridHandler(grid)) as Record<string | number, GridCell>; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function getGridHandler(grid: GenericGrid): ProxyHandler<Record<string | number, GridCell>> { + const keys = computed(() => { + const keys = []; + for (let row = 1; row <= unref(grid.rows); row++) { + for (let col = 1; col <= unref(grid.cols); col++) { + keys.push((row * 100 + col).toString()); + } + } + return keys; + }); + return { + get(target: Record<string | number, GridCell>, key: PropertyKey) { + if (key === "isProxy") { + return true; + } + + if (typeof key === "symbol") { + return (grid as never)[key]; + } + + if (!keys.value.includes(key.toString())) { + return undefined; + } + + if (target[key] == null) { + target[key] = new Proxy( + grid, + getCellHandler(key.toString()) + ) as unknown as GridCell; + } + + return target[key]; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + set(target: Record<string | number, GridCell>, key: PropertyKey, value: any) { + console.warn("Cannot set grid cells", target, key, value); + return false; + }, + ownKeys() { + return keys.value; + }, + has(target: Record<string | number, GridCell>, key: PropertyKey) { + return keys.value.includes(key.toString()); + }, + getOwnPropertyDescriptor(target: Record<string | number, GridCell>, key: PropertyKey) { + if (keys.value.includes(key.toString())) { + return { + configurable: true, + enumerable: true, + writable: false + }; + } + } + }; +} + +function getCellHandler(id: string): ProxyHandler<GenericGrid> { + const keys = [ + "id", + "visibility", + "canClick", + "startState", + "state", + "style", + "classes", + "title", + "display", + "onClick", + "onHold" + ]; + const cache: Record<string, Ref<unknown>> = {}; + return { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + get(target, key, receiver): any { + if (key === "isProxy") { + return true; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let prop = (target as any)[key]; + + if (isFunction(prop)) { + return () => prop.call(receiver, id, target.getState(id)); + } + if (prop != undefined || typeof key === "symbol") { + return prop; + } + + key = key.slice(0, 1).toUpperCase() + key.slice(1); + + if (key === "startState") { + return prop.call(receiver, id); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + prop = (target as any)[`get${key}`]; + if (isFunction(prop)) { + if (!(key in cache)) { + cache[key] = computed(() => prop.call(receiver, id, target.getState(id))); + } + return cache[key].value; + } else if (prop != undefined) { + return unref(prop); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + prop = (target as any)[`on${key}`]; + if (isFunction(prop)) { + return () => prop.call(receiver, id, target.getState(id)); + } else if (prop != undefined) { + return prop; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (target as any)[key]; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + set(target: Record<string, any>, key: string, value: any, receiver: typeof Proxy): boolean { + key = `set${key.slice(0, 1).toUpperCase() + key.slice(1)}`; + if (key in target && isFunction(target[key]) && target[key].length < 3) { + target[key].call(receiver, id, value); + return true; + } else { + console.warn(`No setter for "${key}".`, target); + return false; + } + }, + ownKeys() { + return keys; + }, + has(target, key) { + return keys.includes(key.toString()); + }, + getOwnPropertyDescriptor(target, key) { + if (keys.includes(key.toString())) { + return { + configurable: true, + enumerable: true, + writable: false + }; + } + } + }; +} + +export interface GridCell { + id: string; + visibility: Visibility; + canClick: boolean; + startState: State; + state: State; + style?: StyleValue; + classes?: Record<string, boolean>; + title?: CoercableComponent; + display: CoercableComponent; + onClick?: (e?: MouseEvent | TouchEvent) => void; + onHold?: VoidFunction; +} + +export interface GridOptions { + visibility?: Computable<Visibility>; + rows: Computable<number>; + cols: Computable<number>; + getVisibility?: CellComputable<Visibility>; + getCanClick?: CellComputable<boolean>; + getStartState: Computable<State> | ((id: string | number) => State); + getStyle?: CellComputable<StyleValue>; + getClasses?: CellComputable<Record<string, boolean>>; + getTitle?: CellComputable<CoercableComponent>; + getDisplay: CellComputable<CoercableComponent>; + onClick?: (id: string | number, state: State, e?: MouseEvent | TouchEvent) => void; + onHold?: (id: string | number, state: State) => void; +} + +export interface BaseGrid { + id: string; + getID: (id: string | number, state: State) => string; + getState: (id: string | number) => State; + setState: (id: string | number, state: State) => void; + cells: Record<string | number, GridCell>; + cellState: Persistent<Record<string | number, State>>; + type: typeof GridType; + [Component]: typeof GridComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Grid<T extends GridOptions> = Replace< + T & BaseGrid, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + rows: GetComputableType<T["rows"]>; + cols: GetComputableType<T["cols"]>; + getVisibility: GetComputableTypeWithDefault<T["getVisibility"], Visibility.Visible>; + getCanClick: GetComputableTypeWithDefault<T["getCanClick"], true>; + getStartState: GetComputableType<T["getStartState"]>; + getStyle: GetComputableType<T["getStyle"]>; + getClasses: GetComputableType<T["getClasses"]>; + getTitle: GetComputableType<T["getTitle"]>; + getDisplay: GetComputableType<T["getDisplay"]>; + } +>; + +export type GenericGrid = Replace< + Grid<GridOptions>, + { + visibility: ProcessedComputable<Visibility>; + getVisibility: ProcessedComputable<Visibility>; + getCanClick: ProcessedComputable<boolean>; + } +>; + +export function createGrid<T extends GridOptions>( + optionsFunc: OptionsFunc<T, BaseGrid, GenericGrid> +): Grid<T> { + const cellState = persistent<Record<string | number, State>>({}); + return createLazyProxy(() => { + const grid = optionsFunc(); + grid.id = getUniqueID("grid-"); + grid[Component] = GridComponent; + + grid.cellState = cellState; + + grid.getID = function (this: GenericGrid, cell: string | number) { + return grid.id + "-" + cell; + }; + grid.getState = function (this: GenericGrid, cell: string | number) { + if (this.cellState.value[cell] != undefined) { + return cellState.value[cell]; + } + return this.cells[cell].startState; + }; + grid.setState = function (this: GenericGrid, cell: string | number, state: State) { + cellState.value[cell] = state; + }; + + grid.cells = createGridProxy(grid as GenericGrid); + + processComputable(grid as T, "visibility"); + setDefault(grid, "visibility", Visibility.Visible); + processComputable(grid as T, "rows"); + processComputable(grid as T, "cols"); + processComputable(grid as T, "getVisibility"); + setDefault(grid, "getVisibility", Visibility.Visible); + processComputable(grid as T, "getCanClick"); + setDefault(grid, "getCanClick", true); + processComputable(grid as T, "getStartState"); + processComputable(grid as T, "getStyle"); + processComputable(grid as T, "getClasses"); + processComputable(grid as T, "getTitle"); + processComputable(grid as T, "getDisplay"); + + if (grid.onClick) { + const onClick = grid.onClick.bind(grid); + grid.onClick = function (id, state) { + if (unref((grid as GenericGrid).cells[id].canClick)) { + onClick(id, state); + } + }; + } + if (grid.onHold) { + const onHold = grid.onHold.bind(grid); + grid.onHold = function (id, state) { + if (unref((grid as GenericGrid).cells[id].canClick)) { + onHold(id, state); + } + }; + } + + grid[GatherProps] = function (this: GenericGrid) { + const { visibility, rows, cols, cells, id } = this; + return { visibility, rows, cols, cells, id }; + }; + + return grid as unknown as Grid<T>; + }); +} diff --git a/src/features/hotkey.tsx b/src/features/hotkey.tsx new file mode 100644 index 0000000..bfb958f --- /dev/null +++ b/src/features/hotkey.tsx @@ -0,0 +1,112 @@ +import { hasWon } from "data/projEntry"; +import type { OptionsFunc, Replace } from "features/feature"; +import { findFeatures, jsx, setDefault } from "features/feature"; +import { globalBus } from "game/events"; +import player from "game/player"; +import { registerInfoComponent } from "game/settings"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { shallowReactive, unref } from "vue"; + +export const hotkeys: Record<string, GenericHotkey | undefined> = shallowReactive({}); +export const HotkeyType = Symbol("Hotkey"); + +export interface HotkeyOptions { + enabled?: Computable<boolean>; + key: string; + description: Computable<string>; + onPress: VoidFunction; +} + +export interface BaseHotkey { + type: typeof HotkeyType; +} + +export type Hotkey<T extends HotkeyOptions> = Replace< + T & BaseHotkey, + { + enabled: GetComputableTypeWithDefault<T["enabled"], true>; + description: GetComputableType<T["description"]>; + } +>; + +export type GenericHotkey = Replace< + Hotkey<HotkeyOptions>, + { + enabled: ProcessedComputable<boolean>; + } +>; + +export function createHotkey<T extends HotkeyOptions>( + optionsFunc: OptionsFunc<T, BaseHotkey, GenericHotkey> +): Hotkey<T> { + return createLazyProxy(() => { + const hotkey = optionsFunc(); + hotkey.type = HotkeyType; + + processComputable(hotkey as T, "enabled"); + setDefault(hotkey, "enabled", true); + processComputable(hotkey as T, "description"); + + return hotkey as unknown as Hotkey<T>; + }); +} + +globalBus.on("addLayer", layer => { + (findFeatures(layer, HotkeyType) as GenericHotkey[]).forEach(hotkey => { + hotkeys[hotkey.key] = hotkey; + }); +}); + +globalBus.on("removeLayer", layer => { + (findFeatures(layer, HotkeyType) as GenericHotkey[]).forEach(hotkey => { + hotkeys[hotkey.key] = undefined; + }); +}); + +document.onkeydown = function (e) { + if ((e.target as HTMLElement | null)?.tagName === "INPUT") { + return; + } + if (hasWon.value && !player.keepGoing) { + return; + } + let key = e.key; + if (e.shiftKey) { + key = "shift+" + key; + } + if (e.ctrlKey) { + key = "ctrl+" + key; + } + const hotkey = hotkeys[key]; + if (hotkey && unref(hotkey.enabled)) { + e.preventDefault(); + hotkey.onPress(); + } +}; + +registerInfoComponent( + jsx(() => { + const keys = Object.values(hotkeys).filter(hotkey => unref(hotkey?.enabled)); + if (keys.length === 0) { + return ""; + } + return ( + <div> + <br /> + <h4>Hotkeys</h4> + {keys.map(hotkey => ( + <div> + {hotkey?.key}: {hotkey?.description} + </div> + ))} + </div> + ); + }) +); diff --git a/src/features/infoboxes/Infobox.vue b/src/features/infoboxes/Infobox.vue new file mode 100644 index 0000000..2271c1b --- /dev/null +++ b/src/features/infoboxes/Infobox.vue @@ -0,0 +1,181 @@ +<template> + <div + class="infobox" + v-if="unref(visibility) !== Visibility.None" + :style="[ + { + borderColor: unref(color), + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }, + unref(style) ?? {} + ]" + :class="{ collapsed: unref(collapsed), stacked, ...unref(classes) }" + > + <button + class="title" + :style="[{ backgroundColor: unref(color) }, unref(titleStyle) || []]" + @click="collapsed.value = !unref(collapsed)" + > + <span class="toggle">▼</span> + <component :is="titleComponent" /> + </button> + <CollapseTransition> + <div v-if="!unref(collapsed)" class="body" :style="{ backgroundColor: unref(color) }"> + <component :is="bodyComponent" :style="unref(bodyStyle)" /> + </div> + </CollapseTransition> + <Node :id="id" /> + </div> +</template> + +<script lang="ts"> +import CollapseTransition from "@ivanv/vue-collapse-transition/src/CollapseTransition.vue"; +import Node from "components/Node.vue"; +import themes from "data/themes"; +import type { CoercableComponent } from "features/feature"; +import { Visibility } from "features/feature"; +import settings from "game/settings"; +import { computeComponent, processedPropType } from "util/vue"; +import type { PropType, Ref, StyleValue } from "vue"; +import { computed, defineComponent, toRefs, unref } from "vue"; + +export default defineComponent({ + props: { + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + display: { + type: processedPropType<CoercableComponent>(Object, String, Function), + required: true + }, + title: { + type: processedPropType<CoercableComponent>(Object, String, Function), + required: true + }, + color: processedPropType<string>(String), + collapsed: { + type: Object as PropType<Ref<boolean>>, + required: true + }, + style: processedPropType<StyleValue>(Object, String, Array), + titleStyle: processedPropType<StyleValue>(Object, String, Array), + bodyStyle: processedPropType<StyleValue>(Object, String, Array), + classes: processedPropType<Record<string, boolean>>(Object), + id: { + type: String, + required: true + } + }, + components: { + Node, + CollapseTransition + }, + setup(props) { + const { title, display } = toRefs(props); + + const titleComponent = computeComponent(title); + const bodyComponent = computeComponent(display); + const stacked = computed(() => themes[settings.theme].mergeAdjacent); + + return { + titleComponent, + bodyComponent, + stacked, + unref, + Visibility + }; + } +}); +</script> + +<style scoped> +.infobox { + position: relative; + width: 600px; + max-width: 95%; + margin-top: 0; + text-align: left; + border-style: solid; + border-width: 0px; + box-sizing: border-box; + border-radius: 5px; +} + +.infobox.stacked { + border-width: 4px; +} + +.infobox:not(.stacked) + .infobox:not(.stacked) { + margin-top: 20px; +} + +.infobox + :not(.infobox) { + margin-top: 10px; +} + +.title { + font-size: 24px; + color: black; + cursor: pointer; + border: none; + padding: 4px; + width: auto; + text-align: left; + padding-left: 30px; +} + +.infobox:not(.stacked) .title { + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.infobox.stacked + .infobox.stacked { + border-top-left-radius: 0; + border-top-right-radius: 0; + margin-top: -5px; +} + +.stacked .title { + width: 100%; +} + +.collapsed:not(.stacked) .title::after { + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 4px; + background-color: inherit; +} + +.toggle { + position: absolute; + left: 10px; +} + +.collapsed .toggle { + transform: rotate(-90deg); +} + +.body { + transition-duration: 0.5s; + border-radius: 5px; + border-top-left-radius: 0; +} + +.infobox:not(.stacked) .body { + padding: 4px; +} + +.body > * { + padding: 8px; + width: 100%; + display: block; + box-sizing: border-box; + border-radius: 5px; + border-top-left-radius: 0; + background-color: var(--background); +} +</style> diff --git a/src/features/infoboxes/infobox.ts b/src/features/infoboxes/infobox.ts new file mode 100644 index 0000000..f30e31c --- /dev/null +++ b/src/features/infoboxes/infobox.ts @@ -0,0 +1,109 @@ +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; +import InfoboxComponent from "features/infoboxes/Infobox.vue"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { unref } from "vue"; + +export const InfoboxType = Symbol("Infobox"); + +export interface InfoboxOptions { + visibility?: Computable<Visibility>; + color?: Computable<string>; + style?: Computable<StyleValue>; + titleStyle?: Computable<StyleValue>; + bodyStyle?: Computable<StyleValue>; + classes?: Computable<Record<string, boolean>>; + title: Computable<CoercableComponent>; + display: Computable<CoercableComponent>; +} + +export interface BaseInfobox { + id: string; + collapsed: Persistent<boolean>; + type: typeof InfoboxType; + [Component]: typeof InfoboxComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Infobox<T extends InfoboxOptions> = Replace< + T & BaseInfobox, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + color: GetComputableType<T["color"]>; + style: GetComputableType<T["style"]>; + titleStyle: GetComputableType<T["titleStyle"]>; + bodyStyle: GetComputableType<T["bodyStyle"]>; + classes: GetComputableType<T["classes"]>; + title: GetComputableType<T["title"]>; + display: GetComputableType<T["display"]>; + } +>; + +export type GenericInfobox = Replace< + Infobox<InfoboxOptions>, + { + visibility: ProcessedComputable<Visibility>; + } +>; + +export function createInfobox<T extends InfoboxOptions>( + optionsFunc: OptionsFunc<T, BaseInfobox, GenericInfobox> +): Infobox<T> { + const collapsed = persistent<boolean>(false); + return createLazyProxy(() => { + const infobox = optionsFunc(); + infobox.id = getUniqueID("infobox-"); + infobox.type = InfoboxType; + infobox[Component] = InfoboxComponent; + + infobox.collapsed = collapsed; + + processComputable(infobox as T, "visibility"); + setDefault(infobox, "visibility", Visibility.Visible); + processComputable(infobox as T, "color"); + processComputable(infobox as T, "style"); + processComputable(infobox as T, "titleStyle"); + processComputable(infobox as T, "bodyStyle"); + processComputable(infobox as T, "classes"); + processComputable(infobox as T, "title"); + processComputable(infobox as T, "display"); + + infobox[GatherProps] = function (this: GenericInfobox) { + const { + visibility, + display, + title, + color, + collapsed, + style, + titleStyle, + bodyStyle, + classes, + id + } = this; + return { + visibility, + display, + title, + color, + collapsed, + style: unref(style), + titleStyle, + bodyStyle, + classes, + id + }; + }; + + return infobox as unknown as Infobox<T>; + }); +} diff --git a/src/features/links/Link.vue b/src/features/links/Link.vue new file mode 100644 index 0000000..f7b9580 --- /dev/null +++ b/src/features/links/Link.vue @@ -0,0 +1,57 @@ +<template> + <line + stroke-width="15px" + stroke="white" + v-bind="link" + :x1="startPosition.x" + :y1="startPosition.y" + :x2="endPosition.x" + :y2="endPosition.y" + /> +</template> + +<script setup lang="ts"> +import type { Link } from "features/links/links"; +import type { FeatureNode } from "game/layers"; +import { computed, toRefs } from "vue"; + +const _props = defineProps<{ + link: Link; + startNode: FeatureNode; + endNode: FeatureNode; + boundingRect: DOMRect | undefined; +}>(); +const props = toRefs(_props); + +const startPosition = computed(() => { + const rect = props.startNode.value.rect; + const boundingRect = props.boundingRect.value; + const position = boundingRect + ? { + x: rect.x + rect.width / 2 - boundingRect.x, + y: rect.y + rect.height / 2 - boundingRect.y + } + : { x: 0, y: 0 }; + if (props.link.value.offsetStart) { + position.x += props.link.value.offsetStart.x; + position.y += props.link.value.offsetStart.y; + } + return position; +}); + +const endPosition = computed(() => { + const rect = props.endNode.value.rect; + const boundingRect = props.boundingRect.value; + const position = boundingRect + ? { + x: rect.x + rect.width / 2 - boundingRect.x, + y: rect.y + rect.height / 2 - boundingRect.y + } + : { x: 0, y: 0 }; + if (props.link.value.offsetEnd) { + position.x += props.link.value.offsetEnd.x; + position.y += props.link.value.offsetEnd.y; + } + return position; +}); +</script> diff --git a/src/features/links/Links.vue b/src/features/links/Links.vue new file mode 100644 index 0000000..dafab2b --- /dev/null +++ b/src/features/links/Links.vue @@ -0,0 +1,64 @@ +<template> + <svg v-if="validLinks" v-bind="$attrs"> + <LinkVue + v-for="(link, index) in validLinks" + :key="index" + :link="link" + :boundingRect="boundingRect" + :startNode="nodes[link.startNode.id]!" + :endNode="nodes[link.endNode.id]!" + /> + </svg> + <div ref="resizeListener" class="resize-listener" /> +</template> + +<script setup lang="ts"> +import type { Link } from "features/links/links"; +import type { FeatureNode } from "game/layers"; +import { BoundsInjectionKey, NodesInjectionKey } from "game/layers"; +import { computed, inject, onMounted, ref, toRef, watch } from "vue"; +import LinkVue from "./Link.vue"; + +const _props = defineProps<{ links?: Link[] }>(); +const links = toRef(_props, "links"); + +const resizeListener = ref<Element | null>(null); + +const nodes = inject(NodesInjectionKey, ref<Record<string, FeatureNode | undefined>>({})); +const outerBoundingRect = inject(BoundsInjectionKey, ref<DOMRect | undefined>(undefined)); +const boundingRect = ref<DOMRect | undefined>(resizeListener.value?.getBoundingClientRect()); +watch( + outerBoundingRect, + () => (boundingRect.value = resizeListener.value?.getBoundingClientRect()) +); +onMounted(() => (boundingRect.value = resizeListener.value?.getBoundingClientRect())); + +const validLinks = computed(() => { + const n = nodes.value; + return ( + links.value?.filter(link => n[link.startNode.id]?.rect && n[link.startNode.id]?.rect) ?? [] + ); +}); +</script> + +<style scoped> +.resize-listener { + position: absolute; + top: 0px; + left: 0; + right: -4px; + bottom: 5px; + z-index: -10; + pointer-events: none; +} + +svg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -10; + pointer-events: none; +} +</style> diff --git a/src/features/links/links.ts b/src/features/links/links.ts new file mode 100644 index 0000000..5ab8779 --- /dev/null +++ b/src/features/links/links.ts @@ -0,0 +1,62 @@ +import type { OptionsFunc, Replace } from "features/feature"; +import { GatherProps, Component } from "features/feature"; +import type { Position } from "game/layers"; +import type { Computable, GetComputableType, ProcessedComputable } from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { SVGAttributes } from "vue"; +import LinksComponent from "./Links.vue"; + +export const LinksType = Symbol("Links"); + +export interface Link extends SVGAttributes { + startNode: { id: string }; + endNode: { id: string }; + offsetStart?: Position; + offsetEnd?: Position; +} + +export interface LinksOptions { + links: Computable<Link[]>; +} + +export interface BaseLinks { + type: typeof LinksType; + [Component]: typeof LinksComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Links<T extends LinksOptions> = Replace< + T & BaseLinks, + { + links: GetComputableType<T["links"]>; + } +>; + +export type GenericLinks = Replace< + Links<LinksOptions>, + { + links: ProcessedComputable<Link[]>; + } +>; + +export function createLinks<T extends LinksOptions>( + optionsFunc: OptionsFunc<T, BaseLinks, GenericLinks> +): Links<T> { + return createLazyProxy(() => { + const links = optionsFunc(); + links.type = LinksType; + links[Component] = LinksComponent; + + processComputable(links as T, "links"); + + links[GatherProps] = function (this: GenericLinks) { + const { links } = this; + return { + links + }; + }; + + return links as unknown as Links<T>; + }); +} diff --git a/src/features/milestones/Milestone.vue b/src/features/milestones/Milestone.vue new file mode 100644 index 0000000..92a90d6 --- /dev/null +++ b/src/features/milestones/Milestone.vue @@ -0,0 +1,126 @@ +<template> + <div + v-if="unref(visibility) !== Visibility.None" + :style="[ + { + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }, + unref(style) ?? {} + ]" + :class="{ feature: true, milestone: true, done: unref(earned), ...unref(classes) }" + > + <component :is="unref(comp)" /> + <Node :id="id" /> + </div> +</template> + +<script lang="tsx"> +import "components/common/features.css"; +import Node from "components/Node.vue"; +import type { StyleValue } from "features/feature"; +import { jsx, Visibility } from "features/feature"; +import type { GenericMilestone } from "features/milestones/milestone"; +import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue"; +import type { Component, UnwrapRef } from "vue"; +import { defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue"; + +export default defineComponent({ + props: { + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + display: { + type: processedPropType<UnwrapRef<GenericMilestone["display"]>>( + String, + Object, + Function + ), + required: true + }, + style: processedPropType<StyleValue>(String, Object, Array), + classes: processedPropType<Record<string, boolean>>(Object), + earned: { + type: processedPropType<boolean>(Boolean), + required: true + }, + id: { + type: String, + required: true + } + }, + components: { + Node + }, + setup(props) { + const { display } = toRefs(props); + + const comp = shallowRef<Component | string>(""); + + watchEffect(() => { + const currDisplay = unwrapRef(display); + if (currDisplay == null) { + comp.value = ""; + return; + } + if (isCoercableComponent(currDisplay)) { + comp.value = coerceComponent(currDisplay); + return; + } + const Requirement = coerceComponent(currDisplay.requirement, "h3"); + const EffectDisplay = coerceComponent(currDisplay.effectDisplay || "", "b"); + const OptionsDisplay = coerceComponent(currDisplay.optionsDisplay || "", "span"); + comp.value = coerceComponent( + jsx(() => ( + <span> + <Requirement /> + {currDisplay.effectDisplay ? ( + <div> + <EffectDisplay /> + </div> + ) : null} + {currDisplay.optionsDisplay ? ( + <div class="equal-spaced"> + <OptionsDisplay /> + </div> + ) : null} + </span> + )) + ); + }); + + return { + comp, + unref, + Visibility + }; + } +}); +</script> + +<style scoped> +.milestone { + width: calc(100% - 10px); + min-width: 120px; + padding-left: 5px; + padding-right: 5px; + background-color: var(--locked); + border-width: 4px; + border-radius: 5px; + color: rgba(0, 0, 0, 0.5); +} + +.milestone.done { + background-color: var(--bought); + cursor: default; +} + +.milestone :deep(.equal-spaced) { + display: flex; + justify-content: center; +} + +.milestone :deep(.equal-spaced > *) { + margin: auto; +} +</style> diff --git a/src/features/milestones/milestone.tsx b/src/features/milestones/milestone.tsx new file mode 100644 index 0000000..00badb4 --- /dev/null +++ b/src/features/milestones/milestone.tsx @@ -0,0 +1,192 @@ +import Select from "components/fields/Select.vue"; +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, jsx, setDefault, Visibility } from "features/feature"; +import MilestoneComponent from "features/milestones/Milestone.vue"; +import { globalBus } from "game/events"; +import "game/notifications"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import player from "game/player"; +import settings, { registerSettingField } from "game/settings"; +import { camelToTitle } from "util/common"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { coerceComponent, isCoercableComponent } from "util/vue"; +import { computed, unref, watchEffect } from "vue"; +import { useToast } from "vue-toastification"; + +const toast = useToast(); + +export const MilestoneType = Symbol("Milestone"); + +export enum MilestoneDisplay { + All = "all", + //Last = "last", + Configurable = "configurable", + Incomplete = "incomplete", + None = "none" +} + +export interface MilestoneOptions { + visibility?: Computable<Visibility>; + shouldEarn?: () => boolean; + style?: Computable<StyleValue>; + classes?: Computable<Record<string, boolean>>; + display?: Computable< + | CoercableComponent + | { + requirement: CoercableComponent; + effectDisplay?: CoercableComponent; + optionsDisplay?: CoercableComponent; + } + >; + onComplete?: VoidFunction; +} + +export interface BaseMilestone { + id: string; + earned: Persistent<boolean>; + complete: VoidFunction; + type: typeof MilestoneType; + [Component]: typeof MilestoneComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Milestone<T extends MilestoneOptions> = Replace< + T & BaseMilestone, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + style: GetComputableType<T["style"]>; + classes: GetComputableType<T["classes"]>; + display: GetComputableType<T["display"]>; + } +>; + +export type GenericMilestone = Replace< + Milestone<MilestoneOptions>, + { + visibility: ProcessedComputable<Visibility>; + } +>; + +export function createMilestone<T extends MilestoneOptions>( + optionsFunc?: OptionsFunc<T, BaseMilestone, GenericMilestone> +): Milestone<T> { + const earned = persistent<boolean>(false); + return createLazyProxy(() => { + const milestone = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>); + milestone.id = getUniqueID("milestone-"); + milestone.type = MilestoneType; + milestone[Component] = MilestoneComponent; + + milestone.earned = earned; + milestone.complete = function () { + earned.value = true; + }; + + processComputable(milestone as T, "visibility"); + setDefault(milestone, "visibility", Visibility.Visible); + const visibility = milestone.visibility as ProcessedComputable<Visibility>; + milestone.visibility = computed(() => { + const display = unref((milestone as GenericMilestone).display); + switch (settings.msDisplay) { + default: + case MilestoneDisplay.All: + return unref(visibility); + case MilestoneDisplay.Configurable: + if ( + unref(milestone.earned) && + !( + display != null && + typeof display == "object" && + "optionsDisplay" in (display as Record<string, unknown>) + ) + ) { + return Visibility.None; + } + return unref(visibility); + case MilestoneDisplay.Incomplete: + if (unref(milestone.earned)) { + return Visibility.None; + } + return unref(visibility); + case MilestoneDisplay.None: + return Visibility.None; + } + }); + + processComputable(milestone as T, "style"); + processComputable(milestone as T, "classes"); + processComputable(milestone as T, "display"); + + milestone[GatherProps] = function (this: GenericMilestone) { + const { visibility, display, style, classes, earned, id } = this; + return { visibility, display, style: unref(style), classes, earned, id }; + }; + + if (milestone.shouldEarn) { + const genericMilestone = milestone as GenericMilestone; + watchEffect(() => { + if (settings.active !== player.id) return; + if ( + !genericMilestone.earned.value && + unref(genericMilestone.visibility) === Visibility.Visible && + genericMilestone.shouldEarn?.() + ) { + genericMilestone.earned.value = true; + genericMilestone.onComplete?.(); + if (genericMilestone.display) { + const display = unref(genericMilestone.display); + const Display = coerceComponent( + isCoercableComponent(display) ? display : display.requirement + ); + toast( + <> + <h3>Milestone earned!</h3> + <div> + {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */} + {/* @ts-ignore */} + <Display /> + </div> + </> + ); + } + } + }); + } + + return milestone as unknown as Milestone<T>; + }); +} + +declare module "game/settings" { + interface Settings { + msDisplay: MilestoneDisplay; + } +} + +globalBus.on("loadSettings", settings => { + setDefault(settings, "msDisplay", MilestoneDisplay.All); +}); + +const msDisplayOptions = Object.values(MilestoneDisplay).map(option => ({ + label: camelToTitle(option), + value: option +})); + +registerSettingField( + jsx(() => ( + <Select + title="Show Milestones" + options={msDisplayOptions} + onUpdate:modelValue={value => (settings.msDisplay = value as MilestoneDisplay)} + modelValue={settings.msDisplay} + /> + )) +); diff --git a/src/features/particles/Particles.vue b/src/features/particles/Particles.vue new file mode 100644 index 0000000..1f7de78 --- /dev/null +++ b/src/features/particles/Particles.vue @@ -0,0 +1,94 @@ +<template> + <div + ref="resizeListener" + class="resize-listener" + :style="unref(style)" + :class="unref(classes)" + /> +</template> + +<script lang="tsx"> +import { Application } from "@pixi/app"; +import type { StyleValue } from "features/feature"; +import { globalBus } from "game/events"; +import "lib/pixi"; +import { processedPropType } from "util/vue"; +import type { PropType } from "vue"; +import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, unref } from "vue"; + +// TODO get typing support on the Particles component +export default defineComponent({ + props: { + style: processedPropType<StyleValue>(String, Object, Array), + classes: processedPropType<Record<string, boolean>>(Object), + onInit: { + type: Function as PropType<(app: Application) => void>, + required: true + }, + id: { + type: String, + required: true + }, + onContainerResized: Function as PropType<(rect: DOMRect) => void>, + onHotReload: Function as PropType<VoidFunction> + }, + setup(props) { + const app = shallowRef<null | Application>(null); + + const resizeObserver = new ResizeObserver(updateBounds); + const resizeListener = shallowRef<HTMLElement | null>(null); + + onMounted(() => { + // ResizeListener exists because ResizeObserver's don't work when told to observe an SVG element + const resListener = resizeListener.value; + if (resListener != null) { + resizeObserver.observe(resListener); + app.value = new Application({ + resizeTo: resListener, + backgroundAlpha: 0 + }); + resizeListener.value?.appendChild(app.value.view); + props.onInit?.(app.value as Application); + } + updateBounds(); + if (props.onHotReload) { + nextTick(props.onHotReload); + } + }); + onBeforeUnmount(() => { + app.value?.destroy(); + }); + + let isDirty = true; + function updateBounds() { + if (isDirty) { + isDirty = false; + nextTick(() => { + if (resizeListener.value != null) { + props.onContainerResized?.(resizeListener.value.getBoundingClientRect()); + } + isDirty = true; + }); + } + } + globalBus.on("fontsLoaded", updateBounds); + + return { + unref, + resizeListener + }; + } +}); +</script> + +<style scoped> +.not-fullscreen, +.resize-listener { + position: absolute; + top: 0px; + left: 0; + right: -4px; + bottom: 5px; + pointer-events: none; +} +</style> diff --git a/src/features/particles/particles.tsx b/src/features/particles/particles.tsx new file mode 100644 index 0000000..0b5b23f --- /dev/null +++ b/src/features/particles/particles.tsx @@ -0,0 +1,94 @@ +import { Application } from "@pixi/app"; +import type { EmitterConfigV3 } from "@pixi/particle-emitter"; +import { Emitter, upgradeConfig } from "@pixi/particle-emitter"; +import type { GenericComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID } from "features/feature"; +import ParticlesComponent from "features/particles/Particles.vue"; +import type { Computable, GetComputableType } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { Ref, shallowRef, unref } from "vue"; + +export const ParticlesType = Symbol("Particles"); + +export interface ParticlesOptions { + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + onContainerResized?: (boundingRect: DOMRect) => void; + onHotReload?: VoidFunction; +} + +export interface BaseParticles { + id: string; + app: Ref<null | Application>; + addEmitter: (config: EmitterConfigV3) => Promise<Emitter>; + type: typeof ParticlesType; + [Component]: GenericComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Particles<T extends ParticlesOptions> = Replace< + T & BaseParticles, + { + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + } +>; + +export type GenericParticles = Particles<ParticlesOptions>; + +export function createParticles<T extends ParticlesOptions>( + optionsFunc?: OptionsFunc<T, BaseParticles, GenericParticles> +): Particles<T> { + return createLazyProxy(() => { + const particles = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>); + particles.id = getUniqueID("particles-"); + particles.type = ParticlesType; + particles[Component] = ParticlesComponent; + + particles.app = shallowRef(null); + particles.addEmitter = (config: EmitterConfigV3): Promise<Emitter> => { + const genericParticles = particles as GenericParticles; + if (genericParticles.app.value) { + return Promise.resolve(new Emitter(genericParticles.app.value.stage, config)); + } + return new Promise<Emitter>(resolve => { + emittersToAdd.push({ resolve, config }); + }); + }; + + let emittersToAdd: { + resolve: (value: Emitter | PromiseLike<Emitter>) => void; + config: EmitterConfigV3; + }[] = []; + + function onInit(app: Application) { + const genericParticles = particles as GenericParticles; + genericParticles.app.value = app; + emittersToAdd.forEach(({ resolve, config }) => resolve(new Emitter(app.stage, config))); + emittersToAdd = []; + } + + particles.onContainerResized = particles.onContainerResized?.bind(particles); + + particles[GatherProps] = function (this: GenericParticles) { + const { id, style, classes, onContainerResized, onHotReload } = this; + return { + id, + style: unref(style), + classes, + onContainerResized, + onHotReload, + onInit + }; + }; + + return particles as unknown as Particles<T>; + }); +} + +declare global { + interface Window { + upgradeConfig: typeof upgradeConfig; + } +} +window.upgradeConfig = upgradeConfig; diff --git a/src/features/reset.ts b/src/features/reset.ts new file mode 100644 index 0000000..eaa3631 --- /dev/null +++ b/src/features/reset.ts @@ -0,0 +1,97 @@ +import type { OptionsFunc, Replace } from "features/feature"; +import { getUniqueID } from "features/feature"; +import { globalBus } from "game/events"; +import type { BaseLayer } from "game/layers"; +import type { Persistent } from "game/persistence"; +import { DefaultValue, persistent, PersistentState } from "game/persistence"; +import type { Unsubscribe } from "nanoevents"; +import Decimal from "util/bignum"; +import type { Computable, GetComputableType } from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { isRef, unref } from "vue"; + +export const ResetType = Symbol("Reset"); + +export interface ResetOptions { + thingsToReset: Computable<Record<string, unknown>[]>; + onReset?: VoidFunction; +} + +export interface BaseReset { + id: string; + reset: VoidFunction; + type: typeof ResetType; +} + +export type Reset<T extends ResetOptions> = Replace< + T & BaseReset, + { + thingsToReset: GetComputableType<T["thingsToReset"]>; + } +>; + +export type GenericReset = Reset<ResetOptions>; + +export function createReset<T extends ResetOptions>( + optionsFunc: OptionsFunc<T, BaseReset, GenericReset> +): Reset<T> { + return createLazyProxy(() => { + const reset = optionsFunc(); + reset.id = getUniqueID("reset-"); + reset.type = ResetType; + + reset.reset = function () { + const handleObject = (obj: unknown) => { + if (obj && typeof obj === "object") { + if (PersistentState in obj) { + (obj as Persistent)[PersistentState].value = (obj as Persistent)[ + DefaultValue + ]; + } else if (!(obj instanceof Decimal) && !isRef(obj)) { + Object.values(obj).forEach(obj => + handleObject(obj as Record<string, unknown>) + ); + } + } + }; + unref((reset as GenericReset).thingsToReset).forEach(handleObject); + globalBus.emit("reset", reset as GenericReset); + reset.onReset?.(); + }; + + processComputable(reset as T, "thingsToReset"); + + return reset as unknown as Reset<T>; + }); +} + +const listeners: Record<string, Unsubscribe | undefined> = {}; +export function trackResetTime(layer: BaseLayer, reset: GenericReset): Persistent<Decimal> { + const resetTime = persistent<Decimal>(new Decimal(0)); + globalBus.on("addLayer", layerBeingAdded => { + if (layer.id === layerBeingAdded.id) { + listeners[layer.id]?.(); + listeners[layer.id] = layer.on("preUpdate", diff => { + resetTime.value = Decimal.add(resetTime.value, diff); + }); + } + }); + globalBus.on("reset", currentReset => { + if (currentReset === reset) { + resetTime.value = new Decimal(0); + } + }); + return resetTime; +} +globalBus.on("removeLayer", layer => { + // unsubscribe from preUpdate + listeners[layer.id]?.(); + listeners[layer.id] = undefined; +}); + +declare module "game/events" { + interface GlobalEvents { + reset: (reset: GenericReset) => void; + } +} diff --git a/src/features/resources/MainDisplay.vue b/src/features/resources/MainDisplay.vue new file mode 100644 index 0000000..2367cae --- /dev/null +++ b/src/features/resources/MainDisplay.vue @@ -0,0 +1,57 @@ +<template> + <Sticky> + <div + class="main-display-container" + :style="{ height: `${(effectRef?.$el.clientHeight ?? 0) + 50}px` }" + > + <div class="main-display"> + <span v-if="showPrefix">You have </span> + <ResourceVue :resource="resource" :color="color || 'white'" /> + {{ resource.displayName + }}<!-- remove whitespace --> + <span v-if="effectComponent" + >, <component :is="effectComponent" ref="effectRef" + /></span> + </div> + </div> + </Sticky> +</template> + +<script setup lang="ts"> +import Sticky from "components/layout/Sticky.vue"; +import type { CoercableComponent } from "features/feature"; +import type { Resource } from "features/resources/resource"; +import ResourceVue from "features/resources/Resource.vue"; +import Decimal from "util/bignum"; +import { computeOptionalComponent } from "util/vue"; +import { ComponentPublicInstance, ref, Ref, StyleValue } from "vue"; +import { computed, toRefs } from "vue"; + +const _props = defineProps<{ + resource: Resource; + color?: string; + classes?: Record<string, boolean>; + style?: StyleValue; + effectDisplay?: CoercableComponent; +}>(); +const props = toRefs(_props); + +const effectRef = ref<ComponentPublicInstance | null>(null); + +const effectComponent = computeOptionalComponent( + props.effectDisplay as Ref<CoercableComponent | undefined> +); + +const showPrefix = computed(() => { + return Decimal.lt(props.resource.value, "1e1000"); +}); +</script> + +<style> +.main-display-container { + vertical-align: middle; + margin-bottom: 20px; + display: flex; + transition-duration: 0s; +} +</style> diff --git a/src/features/resources/Resource.vue b/src/features/resources/Resource.vue new file mode 100644 index 0000000..928f2da --- /dev/null +++ b/src/features/resources/Resource.vue @@ -0,0 +1,18 @@ +<template> + <h2 :style="{ color, 'text-shadow': '0px 0px 10px ' + color }"> + {{ amount }} + </h2> +</template> + +<script setup lang="ts"> +import type { Resource } from "features/resources/resource"; +import { displayResource } from "features/resources/resource"; +import { computed } from "vue"; + +const props = defineProps<{ + resource: Resource; + color: string; +}>(); + +const amount = computed(() => displayResource(props.resource)); +</script> diff --git a/src/features/resources/resource.ts b/src/features/resources/resource.ts new file mode 100644 index 0000000..019a3d7 --- /dev/null +++ b/src/features/resources/resource.ts @@ -0,0 +1,124 @@ +import { globalBus } from "game/events"; +import type { State } from "game/persistence"; +import { persistent } from "game/persistence"; +import type { DecimalSource } from "util/bignum"; +import Decimal, { format, formatWhole } from "util/bignum"; +import type { ProcessedComputable } from "util/computed"; +import type { ComputedRef, Ref } from "vue"; +import { computed, isRef, ref, unref, watch } from "vue"; + +export interface Resource<T = DecimalSource> extends Ref<T> { + displayName: string; + precision: number; + small?: boolean; +} + +export function createResource<T extends State>( + defaultValue: T | Ref<T>, + displayName = "points", + precision = 0, + small = undefined +): Resource<T> { + const resource: Partial<Resource<T>> = isRef(defaultValue) + ? defaultValue + : persistent(defaultValue); + resource.displayName = displayName; + resource.precision = precision; + resource.small = small; + return resource as Resource<T>; +} + +export function trackBest(resource: Resource): Ref<DecimalSource> { + const best = persistent(resource.value); + watch(resource, amount => { + if (Decimal.gt(amount, best.value)) { + best.value = amount; + } + }); + return best; +} + +export function trackTotal(resource: Resource): Ref<DecimalSource> { + const total = persistent(resource.value); + watch(resource, (amount, prevAmount) => { + if (Decimal.gt(amount, prevAmount)) { + total.value = Decimal.add(total.value, Decimal.sub(amount, prevAmount)); + } + }); + return total; +} + +const tetra8 = new Decimal("10^^8"); +const e100 = new Decimal("1e100"); +export function trackOOMPS( + resource: Resource, + pointGain?: ComputedRef<DecimalSource> +): Ref<string> { + const oomps = ref<DecimalSource>(0); + const oompsMag = ref(0); + const lastPoints = ref<DecimalSource>(0); + + globalBus.on("update", diff => { + oompsMag.value = 0; + if (Decimal.lte(resource.value, e100)) { + lastPoints.value = resource.value; + return; + } + + let curr = resource.value; + let prev = lastPoints.value; + lastPoints.value = curr; + if (Decimal.gt(curr, prev)) { + if (Decimal.gte(curr, tetra8)) { + curr = Decimal.slog(curr, 1e10); + prev = Decimal.slog(prev, 1e10); + oomps.value = curr.sub(prev).div(diff); + oompsMag.value = -1; + } else { + while ( + Decimal.div(curr, prev).log(10).div(diff).gte("100") && + oompsMag.value <= 5 && + Decimal.gt(prev, 0) + ) { + curr = Decimal.log10(curr); + prev = Decimal.log10(prev); + oomps.value = curr.sub(prev).div(diff); + oompsMag.value++; + } + } + } + }); + + const oompsString = computed(() => { + if (oompsMag.value === 0) { + return pointGain + ? format(pointGain.value, resource.precision, resource.small) + + " " + + resource.displayName + + "/s" + : ""; + } + return ( + format(oomps.value) + + " OOM" + + (oompsMag.value < 0 ? "^OOM" : "^" + oompsMag.value) + + "s/sec" + ); + }); + return oompsString; +} + +export function displayResource(resource: Resource, overrideAmount?: DecimalSource): string { + const amount = overrideAmount ?? resource.value; + if (Decimal.eq(resource.precision, 0)) { + return formatWhole(amount); + } + return format(amount, resource.precision, resource.small); +} + +export function unwrapResource(resource: ProcessedComputable<Resource>): Resource { + if ("displayName" in resource) { + return resource; + } + return unref(resource); +} diff --git a/src/features/tabs/Tab.vue b/src/features/tabs/Tab.vue new file mode 100644 index 0000000..103cdf6 --- /dev/null +++ b/src/features/tabs/Tab.vue @@ -0,0 +1,13 @@ +<template> + <component :is="component" /> +</template> + +<script setup lang="ts"> +import type { CoercableComponent } from "features/feature"; +import { computeComponent } from "util/vue"; +import { toRefs } from "vue"; + +const _props = defineProps<{ display: CoercableComponent }>(); +const { display } = toRefs(_props); +const component = computeComponent(display); +</script> diff --git a/src/features/tabs/TabButton.vue b/src/features/tabs/TabButton.vue new file mode 100644 index 0000000..c9347d1 --- /dev/null +++ b/src/features/tabs/TabButton.vue @@ -0,0 +1,114 @@ +<template> + <button + v-if="unref(visibility) !== Visibility.None" + @click="selectTab" + class="tabButton" + :style="[ + { + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }, + glowColorStyle, + unref(style) ?? {} + ]" + :class="{ + active, + ...unref(classes) + }" + > + <component :is="component" /> + </button> +</template> + +<script lang="ts"> +import type { CoercableComponent, StyleValue } from "features/feature"; +import { Visibility } from "features/feature"; +import { getNotifyStyle } from "game/notifications"; +import { computeComponent, processedPropType, unwrapRef } from "util/vue"; +import { computed, defineComponent, toRefs, unref } from "vue"; + +export default defineComponent({ + props: { + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + display: { + type: processedPropType<CoercableComponent>(Object, String, Function), + required: true + }, + style: processedPropType<StyleValue>(String, Object, Array), + classes: processedPropType<Record<string, boolean>>(Object), + glowColor: processedPropType<string>(String), + active: Boolean, + floating: Boolean + }, + emits: ["selectTab"], + setup(props, { emit }) { + const { display, glowColor, floating } = toRefs(props); + + const component = computeComponent(display); + + const glowColorStyle = computed(() => { + const color = unwrapRef(glowColor); + if (!color) { + return {}; + } + if (unref(floating)) { + return getNotifyStyle(color); + } + return { boxShadow: `0px 9px 5px -6px ${color}` }; + }); + + function selectTab() { + emit("selectTab"); + } + + return { + selectTab, + component, + glowColorStyle, + unref, + Visibility + }; + } +}); +</script> + +<style scoped> +.tabButton { + background-color: transparent; + color: var(--foreground); + font-size: 20px; + cursor: pointer; + padding: 5px 20px; + margin: 5px; + border-radius: 5px; + border: 2px solid; + flex-shrink: 0; + border-color: var(--layer-color); +} + +.tabButton:hover { + transform: scale(1.1, 1.1); + text-shadow: 0 0 7px var(--foreground); +} + +:not(.floating) > .tabButton { + height: 50px; + margin: 0; + border-left: none; + border-right: none; + border-top: none; + border-bottom-width: 4px; + border-radius: 0; + transform: unset; +} + +:not(.floating) .tabButton:not(.active) { + border-bottom-color: transparent; +} + +.tabButton > * { + pointer-events: none; +} +</style> diff --git a/src/features/tabs/TabFamily.vue b/src/features/tabs/TabFamily.vue new file mode 100644 index 0000000..1ae9007 --- /dev/null +++ b/src/features/tabs/TabFamily.vue @@ -0,0 +1,247 @@ +<template> + <div + v-if="unref(visibility) !== Visibility.None" + class="tab-family-container" + :class="{ ...unref(classes), ...tabClasses }" + :style="[ + { + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }, + unref(style) ?? [], + tabStyle ?? [] + ]" + > + <Sticky + class="tab-buttons-container" + :class="unref(buttonContainerClasses)" + :style="unref(buttonContainerStyle)" + > + <div class="tab-buttons" :class="{ floating }"> + <TabButton + v-for="(button, id) in unref(tabs)" + @selectTab="selected.value = id" + :floating="floating" + :key="id" + :active="unref(button.tab) === unref(activeTab)" + v-bind="gatherButtonProps(button)" + /> + </div> + </Sticky> + <template v-if="unref(activeTab)"> + <component :is="unref(component)" /> + </template> + </div> +</template> + +<script lang="ts"> +import Sticky from "components/layout/Sticky.vue"; +import themes from "data/themes"; +import type { CoercableComponent, StyleValue } from "features/feature"; +import { Visibility } from "features/feature"; +import type { GenericTab } from "features/tabs/tab"; +import TabButton from "features/tabs/TabButton.vue"; +import type { GenericTabButton } from "features/tabs/tabFamily"; +import settings from "game/settings"; +import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue"; +import type { Component, PropType, Ref } from "vue"; +import { computed, defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue"; + +export default defineComponent({ + props: { + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + activeTab: { + type: processedPropType<GenericTab | CoercableComponent | null>(Object), + required: true + }, + selected: { + type: Object as PropType<Ref<string>>, + required: true + }, + tabs: { + type: processedPropType<Record<string, GenericTabButton>>(Object), + required: true + }, + style: processedPropType<StyleValue>(String, Object, Array), + classes: processedPropType<Record<string, boolean>>(Object), + buttonContainerStyle: processedPropType<StyleValue>(String, Object, Array), + buttonContainerClasses: processedPropType<Record<string, boolean>>(Object) + }, + components: { + Sticky, + TabButton + }, + setup(props) { + const { activeTab } = toRefs(props); + + const floating = computed(() => { + return themes[settings.theme].floatingTabs; + }); + + const component = shallowRef<Component | string>(""); + + watchEffect(() => { + const currActiveTab = unwrapRef(activeTab); + if (currActiveTab == null) { + component.value = ""; + return; + } + if (isCoercableComponent(currActiveTab)) { + component.value = coerceComponent(currActiveTab); + return; + } + component.value = coerceComponent(unref(currActiveTab.display)); + }); + + const tabClasses = computed(() => { + const currActiveTab = unwrapRef(activeTab); + const tabClasses = + isCoercableComponent(currActiveTab) || !currActiveTab + ? undefined + : unref(currActiveTab.classes); + return tabClasses; + }); + + const tabStyle = computed(() => { + const currActiveTab = unwrapRef(activeTab); + return isCoercableComponent(currActiveTab) || !currActiveTab + ? undefined + : unref(currActiveTab.style); + }); + + function gatherButtonProps(button: GenericTabButton) { + const { display, style, classes, glowColor, visibility } = button; + return { display, style: unref(style), classes, glowColor, visibility }; + } + + return { + floating, + tabClasses, + tabStyle, + Visibility, + component, + gatherButtonProps, + unref + }; + } +}); +</script> + +<style scoped> +.tab-family-container { + margin: calc(50px + var(--feature-margin)) 20px var(--feature-margin) 20px; + position: relative; + border: solid 4px; + border-color: var(--outline); +} + +.layer-tab > .tab-family-container:first-child { + margin: -4px -11px var(--feature-margin) -11px; +} + +.layer-tab > .tab-family-container:first-child:nth-last-child(3) { + border-bottom-style: none; + border-left-style: none; + border-right-style: none; + height: calc(100% + 50px); +} + +.modal-body > .tab-family-container:first-child { + margin: calc(10px + var(--feature-margin)) 10px 0 10px; + border: none; +} + +.tab-family-container > :nth-child(2) { + margin-top: 20px; +} + +.modal-body > .tab-family-container > :nth-child(2) { + /* TODO Why does it need this instead of 20px? */ + margin-top: 50px; +} + +.tab-family-container[data-v-f18896fc] > :last-child { + margin-bottom: 20px; +} + +.tab-buttons-container { + z-index: 4; +} + +.tab-buttons-container:not(.floating) { + border-bottom: solid 4px; + border-color: inherit; +} + +:not(.layer-tab):not(.modal-body) > .tab-family-container > .tab-buttons-container:not(.floating) { + width: calc(100% + 6px); + margin-left: -3px; +} + +.tab-buttons-container:not(.floating) .tab-buttons { + text-align: left; + margin-bottom: -4px; +} + +.tab-buttons-container.floating .tab-buttons { + justify-content: center; + margin-top: -25px; +} + +.tab-buttons { + margin-bottom: 24px; + display: flex; + flex-flow: wrap; + z-index: 4; +} + +.layer-tab + > .tab-family-container:first-child:nth-last-child(3) + > .tab-buttons-container + > .tab-buttons { + padding-right: 60px; +} + +.tab-buttons:not(.floating) { + text-align: left; + border-bottom: inherit; + border-width: 4px; + box-sizing: border-box; + height: 50px; +} + +.modal-body .tab-buttons { + width: 100%; + margin-left: 0; + margin-right: 0; + padding-left: 0; +} + +.showGoBack + > .tab-family-container + > .tab-buttons-container:not(.floating):first-child + .tab-buttons { + padding-left: 70px; +} + +:not(.showGoBack) + > .tab-family-container + > .tab-buttons-container:not(.floating):first-child + .tab-buttons { + padding-left: 0; +} + +.minimizable > .tab-buttons-container:not(.floating):first-child { + padding-right: 50px; +} + +.tab-buttons-container:not(.floating):first-child .tab-buttons { + margin-top: -50px; +} + +.tab-buttons-container + * { + margin-top: 20px; +} +</style> diff --git a/src/features/tabs/tab.ts b/src/features/tabs/tab.ts new file mode 100644 index 0000000..3f205fc --- /dev/null +++ b/src/features/tabs/tab.ts @@ -0,0 +1,49 @@ +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID } from "features/feature"; +import TabComponent from "features/tabs/Tab.vue"; +import type { Computable, GetComputableType } from "util/computed"; +import { createLazyProxy } from "util/proxies"; + +export const TabType = Symbol("Tab"); + +export interface TabOptions { + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + display: Computable<CoercableComponent>; +} + +export interface BaseTab { + id: string; + type: typeof TabType; + [Component]: typeof TabComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Tab<T extends TabOptions> = Replace< + T & BaseTab, + { + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + display: GetComputableType<T["display"]>; + } +>; + +export type GenericTab = Tab<TabOptions>; + +export function createTab<T extends TabOptions>( + optionsFunc: OptionsFunc<T, BaseTab, GenericTab> +): Tab<T> { + return createLazyProxy(() => { + const tab = optionsFunc(); + tab.id = getUniqueID("tab-"); + tab.type = TabType; + tab[Component] = TabComponent; + + tab[GatherProps] = function (this: GenericTab) { + const { display } = this; + return { display }; + }; + + return tab as unknown as Tab<T>; + }); +} diff --git a/src/features/tabs/tabFamily.ts b/src/features/tabs/tabFamily.ts new file mode 100644 index 0000000..a1281e0 --- /dev/null +++ b/src/features/tabs/tabFamily.ts @@ -0,0 +1,175 @@ +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; +import TabButtonComponent from "features/tabs/TabButton.vue"; +import TabFamilyComponent from "features/tabs/TabFamily.vue"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { Ref } from "vue"; +import { computed, unref } from "vue"; +import type { GenericTab } from "./tab"; + +export const TabButtonType = Symbol("TabButton"); +export const TabFamilyType = Symbol("TabFamily"); + +export interface TabButtonOptions { + visibility?: Computable<Visibility>; + tab: Computable<GenericTab | CoercableComponent>; + display: Computable<CoercableComponent>; + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + glowColor?: Computable<string>; +} + +export interface BaseTabButton { + type: typeof TabButtonType; + [Component]: typeof TabButtonComponent; +} + +export type TabButton<T extends TabButtonOptions> = Replace< + T & BaseTabButton, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + tab: GetComputableType<T["tab"]>; + display: GetComputableType<T["display"]>; + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + glowColor: GetComputableType<T["glowColor"]>; + } +>; + +export type GenericTabButton = Replace< + TabButton<TabButtonOptions>, + { + visibility: ProcessedComputable<Visibility>; + } +>; + +export interface TabFamilyOptions { + visibility?: Computable<Visibility>; + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + buttonContainerClasses?: Computable<Record<string, boolean>>; + buttonContainerStyle?: Computable<StyleValue>; +} + +export interface BaseTabFamily { + id: string; + tabs: Record<string, TabButtonOptions>; + activeTab: Ref<GenericTab | CoercableComponent | null>; + selected: Persistent<string>; + type: typeof TabFamilyType; + [Component]: typeof TabFamilyComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type TabFamily<T extends TabFamilyOptions> = Replace< + T & BaseTabFamily, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + tabs: Record<string, GenericTabButton>; + } +>; + +export type GenericTabFamily = Replace< + TabFamily<TabFamilyOptions>, + { + visibility: ProcessedComputable<Visibility>; + } +>; + +export function createTabFamily<T extends TabFamilyOptions>( + tabs: Record<string, () => TabButtonOptions>, + optionsFunc?: OptionsFunc<T, BaseTabFamily, GenericTabFamily> +): TabFamily<T> { + if (Object.keys(tabs).length === 0) { + console.warn("Cannot create tab family with 0 tabs"); + throw "Cannot create tab family with 0 tabs"; + } + + const selected = persistent(Object.keys(tabs)[0]); + return createLazyProxy(() => { + const tabFamily = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>); + + tabFamily.id = getUniqueID("tabFamily-"); + tabFamily.type = TabFamilyType; + tabFamily[Component] = TabFamilyComponent; + + tabFamily.tabs = Object.keys(tabs).reduce<Record<string, GenericTabButton>>( + (parsedTabs, tab) => { + const tabButton: TabButtonOptions & Partial<BaseTabButton> = tabs[tab](); + tabButton.type = TabButtonType; + tabButton[Component] = TabButtonComponent; + + processComputable(tabButton as TabButtonOptions, "visibility"); + setDefault(tabButton, "visibility", Visibility.Visible); + processComputable(tabButton as TabButtonOptions, "tab"); + processComputable(tabButton as TabButtonOptions, "display"); + processComputable(tabButton as TabButtonOptions, "classes"); + processComputable(tabButton as TabButtonOptions, "style"); + processComputable(tabButton as TabButtonOptions, "glowColor"); + parsedTabs[tab] = tabButton as GenericTabButton; + return parsedTabs; + }, + {} + ); + tabFamily.selected = selected; + tabFamily.activeTab = computed(() => { + const tabs = unref(processedTabFamily.tabs); + if ( + selected.value in tabs && + unref(tabs[selected.value].visibility) === Visibility.Visible + ) { + return unref(tabs[selected.value].tab); + } + const firstTab = Object.values(tabs).find( + tab => unref(tab.visibility) === Visibility.Visible + ); + if (firstTab) { + return unref(firstTab.tab); + } + return null; + }); + + processComputable(tabFamily as T, "visibility"); + setDefault(tabFamily, "visibility", Visibility.Visible); + processComputable(tabFamily as T, "classes"); + processComputable(tabFamily as T, "style"); + processComputable(tabFamily as T, "buttonContainerClasses"); + processComputable(tabFamily as T, "buttonContainerStyle"); + + tabFamily[GatherProps] = function (this: GenericTabFamily) { + const { + visibility, + activeTab, + selected, + tabs, + style, + classes, + buttonContainerClasses, + buttonContainerStyle + } = this; + return { + visibility, + activeTab, + selected, + tabs, + style: unref(style), + classes, + buttonContainerClasses, + buttonContainerStyle + }; + }; + + // This is necessary because board.types is different from T and TabFamily + const processedTabFamily = tabFamily as unknown as TabFamily<T>; + return processedTabFamily; + }); +} diff --git a/src/features/tooltips/Tooltip.vue b/src/features/tooltips/Tooltip.vue new file mode 100644 index 0000000..1911186 --- /dev/null +++ b/src/features/tooltips/Tooltip.vue @@ -0,0 +1,226 @@ +<template> + <div + class="tooltip-container" + :class="{ shown: isShown }" + @mouseenter="isHovered = true" + @mouseleave="isHovered = false" + @click.capture="togglePinned" + > + <slot /> + <component v-if="elementComp" :is="elementComp" /> + <transition name="fade"> + <div + v-if="isShown" + class="tooltip" + :class="{ + top: unref(direction) === Direction.Up, + left: unref(direction) === Direction.Left, + right: unref(direction) === Direction.Right, + bottom: unref(direction) === Direction.Down, + ...unref(classes) + }" + :style="[ + { + '--xoffset': unref(xoffset) || '0px', + '--yoffset': unref(yoffset) || '0px' + }, + unref(style) ?? {} + ]" + > + <span v-if="showPin" class="material-icons pinned">push_pin</span> + <component v-if="comp" :is="comp" /> + </div> + </transition> + </div> +</template> + +<script lang="tsx"> +import themes from "data/themes"; +import type { CoercableComponent } from "features/feature"; +import { jsx, StyleValue } from "features/feature"; +import type { Persistent } from "game/persistence"; +import settings from "game/settings"; +import { Direction } from "util/common"; +import type { VueFeature } from "util/vue"; +import { + coerceComponent, + computeOptionalComponent, + processedPropType, + renderJSX, + unwrapRef +} from "util/vue"; +import type { Component, PropType } from "vue"; +import { computed, defineComponent, ref, shallowRef, toRefs, unref } from "vue"; + +export default defineComponent({ + props: { + element: Object as PropType<VueFeature>, + display: { + type: processedPropType<CoercableComponent>(Object, String, Function), + required: true + }, + style: processedPropType<StyleValue>(Object, String, Array), + classes: processedPropType<Record<string, boolean>>(Object), + direction: processedPropType<Direction>(String), + xoffset: processedPropType<string>(String), + yoffset: processedPropType<string>(String), + pinned: Object as PropType<Persistent<boolean>> + }, + setup(props) { + const { element, display, pinned } = toRefs(props); + + const isHovered = ref(false); + const isShown = computed(() => (unwrapRef(pinned) || isHovered.value) && comp.value); + const comp = computeOptionalComponent(display); + + const elementComp = shallowRef<Component | "" | null>( + coerceComponent( + jsx(() => { + const currComponent = unwrapRef(element); + return currComponent == null ? "" : renderJSX(currComponent); + }) + ) + ); + + function togglePinned(e: MouseEvent) { + const isPinned = pinned as unknown as Persistent<boolean> | undefined; // Vue typing :/ + if (e.shiftKey && isPinned) { + isPinned.value = !isPinned.value; + e.stopPropagation(); + e.preventDefault(); + } + } + + const showPin = computed(() => unwrapRef(pinned) && themes[settings.theme].showPin); + + return { + Direction, + isHovered, + isShown, + comp, + elementComp, + unref, + togglePinned, + showPin + }; + } +}); +</script> + +<style scoped> +.tooltip-container { + position: relative; + --xoffset: 0px; + --yoffset: 0px; + text-shadow: none !important; +} + +.tooltip, +.tooltip::after { + pointer-events: none; + position: absolute; +} + +.tooltip { + text-align: center; + width: 150px; + font-size: 14px; + line-height: 1.2; + bottom: calc(100% + var(--yoffset)); + left: calc(50% + var(--xoffset)); + margin-bottom: 5px; + transform: translateX(-50%); + padding: 7px; + border-radius: 3px; + background-color: var(--tooltip-background); + color: var(--points); + z-index: 100 !important; + word-break: break-word; +} + +.tooltip :deep(hr) { + margin: var(--feature-margin) 0; +} + +.shown { + z-index: 10; +} + +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} + +.tooltip::after { + content: " "; + position: absolute; + top: 100%; + bottom: 100%; + left: calc(50% - var(--xoffset)); + width: 0; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: var(--tooltip-background) transparent transparent transparent; +} + +.tooltip.left, +.side-nodes .tooltip:not(.right):not(.bottom):not(.top) { + bottom: calc(50% + var(--yoffset)); + left: unset; + right: calc(100% + var(--xoffset)); + margin-bottom: unset; + margin-right: 5px; + transform: translateY(50%); +} + +.tooltip.left::after, +.side-nodes .tooltip:not(.right):not(.bottom):not(.top)::after { + top: calc(50% + var(--yoffset)); + bottom: unset; + left: 100%; + right: 100%; + margin-left: unset; + margin-top: -5px; + border-color: transparent transparent transparent var(--tooltip-background); +} + +.tooltip.right { + bottom: calc(50% + var(--yoffset)); + left: calc(100% + var(--xoffset)); + margin-bottom: unset; + margin-left: 5px; + transform: translateY(50%); +} + +.tooltip.right::after { + top: calc(50% + var(--yoffset)); + left: 0; + right: 100%; + margin-left: -10px; + margin-top: -5px; + border-color: transparent var(--tooltip-background) transparent transparent; +} + +.tooltip.bottom { + top: calc(100% + var(--yoffset)); + bottom: unset; + left: calc(50% + var(--xoffset)); + margin-bottom: unset; + margin-top: 5px; + transform: translateX(-50%); +} + +.tooltip.bottom::after { + top: 0; + margin-top: -10px; + border-color: transparent transparent var(--tooltip-background) transparent; +} + +.pinned { + position: absolute; + right: -5px; + top: -5px; + transform: rotateZ(45deg); +} +</style> diff --git a/src/features/tooltips/tooltip.ts b/src/features/tooltips/tooltip.ts new file mode 100644 index 0000000..dcc618f --- /dev/null +++ b/src/features/tooltips/tooltip.ts @@ -0,0 +1,108 @@ +import type { CoercableComponent, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, setDefault } from "features/feature"; +import { persistent } from "game/persistence"; +import { Direction } from "util/common"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import type { VueFeature } from "util/vue"; +import type { Ref } from "vue"; +import { nextTick, unref } from "vue"; +import TooltipComponent from "./Tooltip.vue"; + +declare module "@vue/runtime-dom" { + interface CSSProperties { + "--xoffset"?: string; + "--yoffset"?: string; + } +} + +export interface TooltipOptions { + pinnable?: boolean; + display: Computable<CoercableComponent>; + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + direction?: Computable<Direction>; + xoffset?: Computable<string>; + yoffset?: Computable<string>; +} + +export interface BaseTooltip { + pinned?: Ref<boolean>; +} + +export type Tooltip<T extends TooltipOptions> = Replace< + T & BaseTooltip, + { + pinnable: T["pinnable"] extends undefined ? false : T["pinnable"]; + pinned: T["pinnable"] extends true ? Ref<boolean> : undefined; + display: GetComputableType<T["display"]>; + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + direction: GetComputableTypeWithDefault<T["direction"], Direction.Up>; + xoffset: GetComputableType<T["xoffset"]>; + yoffset: GetComputableType<T["yoffset"]>; + } +>; + +export type GenericTooltip = Replace< + Tooltip<TooltipOptions>, + { + pinnable: boolean; + pinned: Ref<boolean> | undefined; + direction: ProcessedComputable<Direction>; + } +>; + +export function addTooltip<T extends TooltipOptions>( + element: VueFeature, + options: T & ThisType<Tooltip<T>> & Partial<BaseTooltip> +): Tooltip<T> { + processComputable(options as T, "display"); + processComputable(options as T, "classes"); + processComputable(options as T, "style"); + processComputable(options as T, "direction"); + setDefault(options, "direction", Direction.Up); + processComputable(options as T, "xoffset"); + processComputable(options as T, "yoffset"); + + if (options.pinnable) { + if ("pinned" in element) { + console.error( + "Cannot add pinnable tooltip to element that already has a property called 'pinned'" + ); + options.pinnable = false; + } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (element as any).pinned = options.pinned = persistent<boolean>(false); + } + } + + nextTick(() => { + const elementComponent = element[Component]; + element[Component] = TooltipComponent; + const elementGatherProps = element[GatherProps].bind(element); + element[GatherProps] = function gatherTooltipProps(this: GenericTooltip) { + const { display, classes, style, direction, xoffset, yoffset, pinned } = this; + return { + element: { + [Component]: elementComponent, + [GatherProps]: elementGatherProps + }, + display, + classes, + style: unref(style), + direction, + xoffset, + yoffset, + pinned + }; + }.bind(options as GenericTooltip); + }); + + return options as unknown as Tooltip<T>; +} diff --git a/src/features/trees/Tree.vue b/src/features/trees/Tree.vue new file mode 100644 index 0000000..cba9fbd --- /dev/null +++ b/src/features/trees/Tree.vue @@ -0,0 +1,105 @@ +<template> + <component :is="nodesComp" /> + <component v-if="leftNodesComp" :is="leftNodesComp" /> + <component v-if="rightNodesComp" :is="rightNodesComp" /> + <Links v-if="branches" :links="unref(branches)" /> +</template> + +<script lang="tsx"> +import "components/common/table.css"; +import { jsx } from "features/feature"; +import Links from "features/links/Links.vue"; +import type { GenericTreeNode, TreeBranch } from "features/trees/tree"; +import { coerceComponent, processedPropType, renderJSX, unwrapRef } from "util/vue"; +import type { Component } from "vue"; +import { defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue"; + +export default defineComponent({ + props: { + nodes: { + type: processedPropType<GenericTreeNode[][]>(Array), + required: true + }, + leftSideNodes: processedPropType<GenericTreeNode[]>(Array), + rightSideNodes: processedPropType<GenericTreeNode[]>(Array), + branches: processedPropType<TreeBranch[]>(Array) + }, + components: { Links }, + setup(props) { + const { nodes, leftSideNodes, rightSideNodes } = toRefs(props); + + const nodesComp = shallowRef<Component | "">(); + watchEffect(() => { + const currNodes = unwrapRef(nodes); + nodesComp.value = coerceComponent( + jsx(() => ( + <> + {currNodes.map(row => ( + <span class="row tree-row" style="margin: 50px auto;"> + {row.map(renderJSX)} + </span> + ))} + </> + )) + ); + }); + + const leftNodesComp = shallowRef<Component | "">(); + watchEffect(() => { + const currNodes = unwrapRef(leftSideNodes); + leftNodesComp.value = currNodes + ? coerceComponent( + jsx(() => ( + <span class="left-side-nodes small">{currNodes.map(renderJSX)}</span> + )) + ) + : ""; + }); + + const rightNodesComp = shallowRef<Component | "">(); + watchEffect(() => { + const currNodes = unwrapRef(rightSideNodes); + rightNodesComp.value = currNodes + ? coerceComponent( + jsx(() => <span class="side-nodes small">{currNodes.map(renderJSX)}</span>) + ) + : ""; + }); + + return { + unref, + nodesComp, + leftNodesComp, + rightNodesComp + }; + } +}); +</script> + +<style scoped> +.left-side-nodes { + position: absolute; + left: 15px; + top: 65px; +} + +.side-nodes { + position: absolute; + right: 15px; + top: 65px; +} + +.left-side-nodes :deep(.treeNode), +.side-nodes :deep(.treeNode) { + margin: 20px auto; +} + +.small :deep(.treeNode) { + height: 60px; + width: 60px; +} + +.small :deep(.treeNode) > *:first-child { + font-size: 30px; +} +</style> diff --git a/src/features/trees/TreeNode.vue b/src/features/trees/TreeNode.vue new file mode 100644 index 0000000..6c6cb09 --- /dev/null +++ b/src/features/trees/TreeNode.vue @@ -0,0 +1,121 @@ +<template> + <div + v-if="unref(visibility) !== Visibility.None" + :style="{ visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined }" + :class="{ + treeNode: true, + can: unref(canClick), + ...unref(classes) + }" + @click="onClick" + @mousedown="start" + @mouseleave="stop" + @mouseup="stop" + @touchstart.passive="start" + @touchend.passive="stop" + @touchcancel.passive="stop" + > + <div + :style="[ + { + backgroundColor: unref(color), + boxShadow: `-4px -4px 4px rgba(0, 0, 0, 0.25) inset, 0 0 20px ${unref( + glowColor + )}` + }, + unref(style) ?? [] + ]" + > + <component :is="unref(comp)" /> + </div> + <MarkNode :mark="unref(mark)" /> + <Node :id="id" /> + </div> +</template> + +<script lang="ts"> +import MarkNode from "components/MarkNode.vue"; +import Node from "components/Node.vue"; +import type { CoercableComponent, StyleValue } from "features/feature"; +import { Visibility } from "features/feature"; +import { + computeOptionalComponent, + isCoercableComponent, + processedPropType, + setupHoldToClick +} from "util/vue"; +import type { PropType } from "vue"; +import { defineComponent, toRefs, unref } from "vue"; + +export default defineComponent({ + props: { + display: processedPropType<CoercableComponent>(Object, String, Function), + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + style: processedPropType<StyleValue>(String, Object, Array), + classes: processedPropType<Record<string, boolean>>(Object), + onClick: Function as PropType<(e?: MouseEvent | TouchEvent) => void>, + onHold: Function as PropType<VoidFunction>, + color: processedPropType<string>(String), + glowColor: processedPropType<string>(String), + canClick: { + type: processedPropType<boolean>(Boolean), + required: true + }, + mark: processedPropType<boolean | string>(Boolean, String), + id: { + type: String, + required: true + } + }, + components: { + MarkNode, + Node + }, + setup(props) { + const { onClick, onHold, display } = toRefs(props); + + const comp = computeOptionalComponent(display); + + const { start, stop } = setupHoldToClick(onClick, onHold); + + return { + start, + stop, + comp, + unref, + Visibility, + isCoercableComponent + }; + } +}); +</script> + +<style scoped> +.treeNode { + height: 100px; + width: 100px; + border-radius: 50%; + padding: 0; + margin: 0 10px 0 10px; +} + +.treeNode > *:first-child { + width: 100%; + height: 100%; + border: 2px solid rgba(0, 0, 0, 0.125); + border-radius: inherit; + font-size: 40px; + color: rgba(0, 0, 0, 0.5); + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25); + box-shadow: -4px -4px 4px rgba(0, 0, 0, 0.25) inset, 0px 0px 20px var(--background); + text-transform: capitalize; + display: flex; +} + +.treeNode > *:first-child > * { + pointer-events: none; +} +</style> diff --git a/src/features/trees/tree.ts b/src/features/trees/tree.ts new file mode 100644 index 0000000..3fbf935 --- /dev/null +++ b/src/features/trees/tree.ts @@ -0,0 +1,305 @@ +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; +import type { Link } from "features/links/links"; +import type { GenericReset } from "features/reset"; +import type { Resource } from "features/resources/resource"; +import { displayResource } from "features/resources/resource"; +import TreeComponent from "features/trees/Tree.vue"; +import TreeNodeComponent from "features/trees/TreeNode.vue"; +import type { DecimalSource } from "util/bignum"; +import Decimal, { format, formatWhole } from "util/bignum"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { convertComputable, processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { Ref } from "vue"; +import { computed, ref, shallowRef, unref } from "vue"; + +export const TreeNodeType = Symbol("TreeNode"); +export const TreeType = Symbol("Tree"); + +export interface TreeNodeOptions { + visibility?: Computable<Visibility>; + canClick?: Computable<boolean>; + color?: Computable<string>; + display?: Computable<CoercableComponent>; + glowColor?: Computable<string>; + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + mark?: Computable<boolean | string>; + reset?: GenericReset; + onClick?: (e?: MouseEvent | TouchEvent) => void; + onHold?: VoidFunction; +} + +export interface BaseTreeNode { + id: string; + type: typeof TreeNodeType; + [Component]: typeof TreeNodeComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type TreeNode<T extends TreeNodeOptions> = Replace< + T & BaseTreeNode, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + canClick: GetComputableTypeWithDefault<T["canClick"], true>; + color: GetComputableType<T["color"]>; + display: GetComputableType<T["display"]>; + glowColor: GetComputableType<T["glowColor"]>; + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + mark: GetComputableType<T["mark"]>; + } +>; + +export type GenericTreeNode = Replace< + TreeNode<TreeNodeOptions>, + { + visibility: ProcessedComputable<Visibility>; + canClick: ProcessedComputable<boolean>; + } +>; + +export function createTreeNode<T extends TreeNodeOptions>( + optionsFunc?: OptionsFunc<T, BaseTreeNode, GenericTreeNode> +): TreeNode<T> { + return createLazyProxy(() => { + const treeNode = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>); + treeNode.id = getUniqueID("treeNode-"); + treeNode.type = TreeNodeType; + treeNode[Component] = TreeNodeComponent; + + processComputable(treeNode as T, "visibility"); + setDefault(treeNode, "visibility", Visibility.Visible); + processComputable(treeNode as T, "canClick"); + setDefault(treeNode, "canClick", true); + processComputable(treeNode as T, "color"); + processComputable(treeNode as T, "display"); + processComputable(treeNode as T, "glowColor"); + processComputable(treeNode as T, "classes"); + processComputable(treeNode as T, "style"); + processComputable(treeNode as T, "mark"); + + if (treeNode.onClick) { + const onClick = treeNode.onClick.bind(treeNode); + treeNode.onClick = function () { + if (unref(treeNode.canClick)) { + onClick(); + } + }; + } + if (treeNode.onHold) { + const onHold = treeNode.onHold.bind(treeNode); + treeNode.onHold = function () { + if (unref(treeNode.canClick)) { + onHold(); + } + }; + } + + treeNode[GatherProps] = function (this: GenericTreeNode) { + const { + display, + visibility, + style, + classes, + onClick, + onHold, + color, + glowColor, + canClick, + mark, + id + } = this; + return { + display, + visibility, + style, + classes, + onClick, + onHold, + color, + glowColor, + canClick, + mark, + id + }; + }; + + return treeNode as unknown as TreeNode<T>; + }); +} + +export interface TreeBranch extends Omit<Link, "startNode" | "endNode"> { + startNode: GenericTreeNode; + endNode: GenericTreeNode; +} + +export interface TreeOptions { + visibility?: Computable<Visibility>; + nodes: Computable<GenericTreeNode[][]>; + leftSideNodes?: Computable<GenericTreeNode[]>; + rightSideNodes?: Computable<GenericTreeNode[]>; + branches?: Computable<TreeBranch[]>; + resetPropagation?: ResetPropagation; + onReset?: (node: GenericTreeNode) => void; +} + +export interface BaseTree { + id: string; + links: Ref<Link[]>; + reset: (node: GenericTreeNode) => void; + isResetting: Ref<boolean>; + resettingNode: Ref<GenericTreeNode | null>; + type: typeof TreeType; + [Component]: typeof TreeComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Tree<T extends TreeOptions> = Replace< + T & BaseTree, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + nodes: GetComputableType<T["nodes"]>; + leftSideNodes: GetComputableType<T["leftSideNodes"]>; + rightSideNodes: GetComputableType<T["rightSideNodes"]>; + branches: GetComputableType<T["branches"]>; + } +>; + +export type GenericTree = Replace< + Tree<TreeOptions>, + { + visibility: ProcessedComputable<Visibility>; + } +>; + +export function createTree<T extends TreeOptions>( + optionsFunc: OptionsFunc<T, BaseTree, GenericTree> +): Tree<T> { + return createLazyProxy(() => { + const tree = optionsFunc(); + tree.id = getUniqueID("tree-"); + tree.type = TreeType; + tree[Component] = TreeComponent; + + tree.isResetting = ref(false); + tree.resettingNode = shallowRef(null); + + tree.reset = function (node) { + const genericTree = tree as GenericTree; + genericTree.isResetting.value = true; + genericTree.resettingNode.value = node; + genericTree.resetPropagation?.(genericTree, node); + genericTree.onReset?.(node); + genericTree.isResetting.value = false; + genericTree.resettingNode.value = null; + }; + tree.links = computed(() => { + const genericTree = tree as GenericTree; + return unref(genericTree.branches) ?? []; + }); + + processComputable(tree as T, "visibility"); + setDefault(tree, "visibility", Visibility.Visible); + processComputable(tree as T, "nodes"); + processComputable(tree as T, "leftSideNodes"); + processComputable(tree as T, "rightSideNodes"); + processComputable(tree as T, "branches"); + + tree[GatherProps] = function (this: GenericTree) { + const { nodes, leftSideNodes, rightSideNodes, branches } = this; + return { nodes, leftSideNodes, rightSideNodes, branches }; + }; + + return tree as unknown as Tree<T>; + }); +} + +export type ResetPropagation = { + (tree: GenericTree, resettingNode: GenericTreeNode): void; +}; + +export const defaultResetPropagation = function ( + tree: GenericTree, + resettingNode: GenericTreeNode +): void { + const nodes = unref(tree.nodes); + const row = nodes.findIndex(nodes => nodes.includes(resettingNode)) - 1; + for (let x = row; x >= 0; x--) { + nodes[x].forEach(node => node.reset?.reset()); + } +}; + +export const invertedResetPropagation = function ( + tree: GenericTree, + resettingNode: GenericTreeNode +): void { + const nodes = unref(tree.nodes); + const row = nodes.findIndex(nodes => nodes.includes(resettingNode)) + 1; + for (let x = row; x < nodes.length; x++) { + nodes[x].forEach(node => node.reset?.reset()); + } +}; + +export const branchedResetPropagation = function ( + tree: GenericTree, + resettingNode: GenericTreeNode +): void { + const visitedNodes = [resettingNode]; + let currentNodes = [resettingNode]; + if (tree.branches != null) { + const branches = unref(tree.branches); + while (currentNodes.length > 0) { + const nextNodes: GenericTreeNode[] = []; + currentNodes.forEach(node => { + branches + .filter(branch => branch.startNode === node || branch.endNode === node) + .map(branch => { + if (branch.startNode === node) { + return branch.endNode; + } + return branch.startNode; + }) + .filter(node => !visitedNodes.includes(node)) + .forEach(node => { + // Check here instead of in the filter because this check's results may + // change as we go through each node + if (!nextNodes.includes(node)) { + nextNodes.push(node); + node.reset?.reset(); + } + }); + }); + currentNodes = nextNodes; + visitedNodes.push(...currentNodes); + } + } +}; + +export function createResourceTooltip( + resource: Resource, + requiredResource: Resource | null = null, + requirement: Computable<DecimalSource> = 0 +): Ref<string> { + const req = convertComputable(requirement); + return computed(() => { + if (requiredResource == null || Decimal.gte(resource.value, unref(req))) { + return displayResource(resource) + " " + resource.displayName; + } + return `Reach ${ + Decimal.eq(requiredResource.precision, 0) + ? formatWhole(unref(req)) + : format(unref(req), requiredResource.precision) + } ${requiredResource.displayName} to unlock (You have ${ + Decimal.eq(requiredResource.precision, 0) + ? formatWhole(requiredResource.value) + : format(requiredResource.value, requiredResource.precision) + })`; + }); +} diff --git a/src/features/upgrades/Upgrade.vue b/src/features/upgrades/Upgrade.vue new file mode 100644 index 0000000..f06ab41 --- /dev/null +++ b/src/features/upgrades/Upgrade.vue @@ -0,0 +1,142 @@ +<template> + <button + v-if="unref(visibility) !== Visibility.None" + :style="[ + { + visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined + }, + unref(style) ?? {} + ]" + @click="purchase" + :class="{ + feature: true, + upgrade: true, + can: unref(canPurchase), + locked: !unref(canPurchase), + bought: unref(bought), + ...unref(classes) + }" + :disabled="!unref(canPurchase)" + > + <component v-if="unref(component)" :is="unref(component)" /> + <MarkNode :mark="unref(mark)" /> + <Node :id="id" /> + </button> +</template> + +<script lang="tsx"> +import "components/common/features.css"; +import MarkNode from "components/MarkNode.vue"; +import Node from "components/Node.vue"; +import type { StyleValue } from "features/feature"; +import { jsx, Visibility } from "features/feature"; +import type { Resource } from "features/resources/resource"; +import { displayResource } from "features/resources/resource"; +import type { GenericUpgrade } from "features/upgrades/upgrade"; +import type { DecimalSource } from "util/bignum"; +import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue"; +import type { Component, PropType, UnwrapRef } from "vue"; +import { defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue"; + +export default defineComponent({ + props: { + display: { + type: processedPropType<UnwrapRef<GenericUpgrade["display"]>>(String, Object, Function), + required: true + }, + visibility: { + type: processedPropType<Visibility>(Number), + required: true + }, + style: processedPropType<StyleValue>(String, Object, Array), + classes: processedPropType<Record<string, boolean>>(Object), + resource: Object as PropType<Resource>, + cost: processedPropType<DecimalSource>(String, Object, Number), + canPurchase: { + type: processedPropType<boolean>(Boolean), + required: true + }, + bought: { + type: processedPropType<boolean>(Boolean), + required: true + }, + mark: processedPropType<boolean | string>(Boolean, String), + id: { + type: String, + required: true + }, + purchase: { + type: Function as PropType<VoidFunction>, + required: true + } + }, + components: { + Node, + MarkNode + }, + setup(props) { + const { display, cost } = toRefs(props); + + const component = shallowRef<Component | string>(""); + + watchEffect(() => { + const currDisplay = unwrapRef(display); + if (currDisplay == null) { + component.value = ""; + return; + } + if (isCoercableComponent(currDisplay)) { + component.value = coerceComponent(currDisplay); + return; + } + const currCost = unwrapRef(cost); + const Title = coerceComponent(currDisplay.title || "", "h3"); + const Description = coerceComponent(currDisplay.description, "div"); + const EffectDisplay = coerceComponent(currDisplay.effectDisplay || ""); + component.value = coerceComponent( + jsx(() => ( + <span> + {currDisplay.title ? ( + <div> + <Title /> + </div> + ) : null} + <Description /> + {currDisplay.effectDisplay ? ( + <div> + Currently: <EffectDisplay /> + </div> + ) : null} + {props.resource != null ? ( + <> + <br /> + Cost: {props.resource && + displayResource(props.resource, currCost)}{" "} + {props.resource?.displayName} + </> + ) : null} + </span> + )) + ); + }); + + return { + component, + unref, + Visibility + }; + } +}); +</script> + +<style scoped> +.upgrade { + min-height: 120px; + width: 120px; + font-size: 10px; +} + +.upgrade > * { + pointer-events: none; +} +</style> diff --git a/src/features/upgrades/upgrade.ts b/src/features/upgrades/upgrade.ts new file mode 100644 index 0000000..1039632 --- /dev/null +++ b/src/features/upgrades/upgrade.ts @@ -0,0 +1,186 @@ +import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import { + Component, + findFeatures, + GatherProps, + getUniqueID, + setDefault, + Visibility +} from "features/feature"; +import type { Resource } from "features/resources/resource"; +import UpgradeComponent from "features/upgrades/Upgrade.vue"; +import type { GenericLayer } from "game/layers"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import type { DecimalSource } from "util/bignum"; +import Decimal from "util/bignum"; +import { isFunction } from "util/common"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { Ref } from "vue"; +import { computed, unref } from "vue"; + +export const UpgradeType = Symbol("Upgrade"); + +export interface UpgradeOptions { + visibility?: Computable<Visibility>; + classes?: Computable<Record<string, boolean>>; + style?: Computable<StyleValue>; + display?: Computable< + | CoercableComponent + | { + title?: CoercableComponent; + description: CoercableComponent; + effectDisplay?: CoercableComponent; + } + >; + mark?: Computable<boolean | string>; + cost?: Computable<DecimalSource>; + resource?: Resource; + canAfford?: Computable<boolean>; + onPurchase?: VoidFunction; +} + +export interface BaseUpgrade { + id: string; + bought: Persistent<boolean>; + canPurchase: Ref<boolean>; + purchase: VoidFunction; + type: typeof UpgradeType; + [Component]: typeof UpgradeComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export type Upgrade<T extends UpgradeOptions> = Replace< + T & BaseUpgrade, + { + visibility: GetComputableTypeWithDefault<T["visibility"], Visibility.Visible>; + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + display: GetComputableType<T["display"]>; + mark: GetComputableType<T["mark"]>; + cost: GetComputableType<T["cost"]>; + canAfford: GetComputableTypeWithDefault<T["canAfford"], Ref<boolean>>; + } +>; + +export type GenericUpgrade = Replace< + Upgrade<UpgradeOptions>, + { + visibility: ProcessedComputable<Visibility>; + canPurchase: ProcessedComputable<boolean>; + } +>; + +export function createUpgrade<T extends UpgradeOptions>( + optionsFunc: OptionsFunc<T, BaseUpgrade, GenericUpgrade> +): Upgrade<T> { + const bought = persistent<boolean>(false); + return createLazyProxy(() => { + const upgrade = optionsFunc(); + upgrade.id = getUniqueID("upgrade-"); + upgrade.type = UpgradeType; + upgrade[Component] = UpgradeComponent; + + if (upgrade.canAfford == null && (upgrade.resource == null || upgrade.cost == null)) { + console.warn( + "Error: can't create upgrade without a canAfford property or a resource and cost property", + upgrade + ); + } + + upgrade.bought = bought; + if (upgrade.canAfford == null) { + upgrade.canAfford = computed(() => { + const genericUpgrade = upgrade as GenericUpgrade; + return ( + genericUpgrade.resource != null && + genericUpgrade.cost != null && + Decimal.gte(genericUpgrade.resource.value, unref(genericUpgrade.cost)) + ); + }); + } else { + processComputable(upgrade as T, "canAfford"); + } + upgrade.canPurchase = computed( + () => + unref((upgrade as GenericUpgrade).visibility) === Visibility.Visible && + unref((upgrade as GenericUpgrade).canAfford) && + !unref(upgrade.bought) + ); + upgrade.purchase = function () { + const genericUpgrade = upgrade as GenericUpgrade; + if (!unref(genericUpgrade.canPurchase)) { + return; + } + if (genericUpgrade.resource != null && genericUpgrade.cost != null) { + genericUpgrade.resource.value = Decimal.sub( + genericUpgrade.resource.value, + unref(genericUpgrade.cost) + ); + } + bought.value = true; + genericUpgrade.onPurchase?.(); + }; + + processComputable(upgrade as T, "visibility"); + setDefault(upgrade, "visibility", Visibility.Visible); + processComputable(upgrade as T, "classes"); + processComputable(upgrade as T, "style"); + processComputable(upgrade as T, "display"); + processComputable(upgrade as T, "mark"); + processComputable(upgrade as T, "cost"); + processComputable(upgrade as T, "resource"); + + upgrade[GatherProps] = function (this: GenericUpgrade) { + const { + display, + visibility, + style, + classes, + resource, + cost, + canPurchase, + bought, + mark, + id, + purchase + } = this; + return { + display, + visibility, + style: unref(style), + classes, + resource, + cost, + canPurchase, + bought, + mark, + id, + purchase + }; + }; + + return upgrade as unknown as Upgrade<T>; + }); +} + +export function setupAutoPurchase( + layer: GenericLayer, + autoActive: Computable<boolean>, + upgrades: GenericUpgrade[] = [] +): void { + upgrades = upgrades || findFeatures(layer, UpgradeType); + const isAutoActive = isFunction(autoActive) ? computed(autoActive) : autoActive; + layer.on("update", () => { + if (unref(isAutoActive)) { + upgrades.forEach(upgrade => upgrade.purchase()); + } + }); +} diff --git a/src/game/events.ts b/src/game/events.ts new file mode 100644 index 0000000..4543e15 --- /dev/null +++ b/src/game/events.ts @@ -0,0 +1,161 @@ +import projInfo from "data/projInfo.json"; +import player from "game/player"; +import type { Settings } from "game/settings"; +import settings from "game/settings"; +import state from "game/state"; +import { createNanoEvents } from "nanoevents"; +import Decimal from "util/bignum"; +import type { App, Ref } from "vue"; +import { watch } from "vue"; +import type { GenericLayer } from "./layers"; + +/** All types of events able to be sent or emitted from the global event bus. */ +export interface GlobalEvents { + /** + * Sent whenever a layer is added. + * @param layer The layer being added. + * @param saveData The layer's save data object within player. + */ + addLayer: (layer: GenericLayer, saveData: Record<string, unknown>) => void; + /** + * Sent whenever a layer is removed. + * @param layer The layer being removed. + */ + removeLayer: (layer: GenericLayer) => void; + /** + * Sent every game tick. Runs the life cycle of the project. + * @param diff The delta time since last tick, in ms. + * @param trueDiff The delta time since last tick, in ms. Unaffected by time modifiers like {@link game/player.Player.devSpeed} or {@link game/player.Player.offlineTime}. Intended for things like updating animations. + */ + update: (diff: number, trueDiff: number) => void; + /** + * Sent when constructing the {@link Settings} object. + * Use it to add default values for custom properties to the object. + * @param settings The settings object being constructed. + * @see {@link features/features.setDefault} for setting default values. + */ + loadSettings: (settings: Partial<Settings>) => void; + /** + * Sent when the game has ended. + */ + gameWon: VoidFunction; + /** + * Sent when setting up the Vue Application instance. + * Use it to register global components or otherwise set up things that should affect Vue globally. + * @param vue The Vue App being constructed. + */ + setupVue: (vue: App) => void; + /** + * Sent whenever a save has finished loading. + * Happens when the page is opened and upon switching saves in the saves manager. + */ + onLoad: VoidFunction; + /** + * Using document.fonts.ready returns too early on firefox, so we use document.fonts.onloadingdone instead, which doesn't accept multiple listeners. + * This event fires when that callback is called. + */ + fontsLoaded: VoidFunction; +} + +/** A global event bus for hooking into {@link GlobalEvents}. */ +export const globalBus = createNanoEvents<GlobalEvents>(); + +let intervalID: NodeJS.Timer | null = null; + +// Not imported immediately due to dependency cycles +// This gets set during startGameLoop(), and will only be used in the update function +let hasWon: null | Ref<boolean> = null; + +function update() { + const now = Date.now(); + let diff = (now - player.time) / 1e3; + player.time = now; + const trueDiff = diff; + + state.lastTenTicks.push(trueDiff); + if (state.lastTenTicks.length > 10) { + state.lastTenTicks = state.lastTenTicks.slice(1); + } + + // Stop here if the game is paused on the win screen + if (hasWon?.value && !player.keepGoing) { + return; + } + // Stop here if the player had a NaN value + if (state.hasNaN) { + return; + } + + diff = Math.max(diff, 0); + + if (player.devSpeed === 0) { + return; + } + + // Add offline time if any + if (player.offlineTime != undefined) { + if (Decimal.gt(player.offlineTime, projInfo.offlineLimit * 3600)) { + player.offlineTime = projInfo.offlineLimit * 3600; + } + if (Decimal.gt(player.offlineTime, 0) && player.devSpeed !== 0) { + const offlineDiff = Math.max(player.offlineTime / 10, diff); + player.offlineTime = player.offlineTime - offlineDiff; + diff += offlineDiff; + } else if (player.devSpeed === 0) { + player.offlineTime += diff; + } + if (!player.offlineProd || Decimal.lt(player.offlineTime, 0)) { + player.offlineTime = null; + } + } + + // Cap at max tick length + diff = Math.min(diff, projInfo.maxTickLength); + + // Apply dev speed + if (player.devSpeed != undefined) { + diff *= player.devSpeed; + } + + if (!Number.isFinite(diff)) { + diff = 1e308; + } + + // Update + if (Decimal.eq(diff, 0)) { + return; + } + + player.timePlayed += diff; + if (!Number.isFinite(player.timePlayed)) { + player.timePlayed = 1e308; + } + globalBus.emit("update", diff, trueDiff); + + if (settings.unthrottled) { + requestAnimationFrame(update); + if (intervalID != null) { + clearInterval(intervalID); + intervalID = null; + } + } else if (intervalID == null) { + intervalID = setInterval(update, 50); + } +} + +/** Starts the game loop for the project, which updates the game in ticks. */ +export async function startGameLoop() { + hasWon = (await import("data/projEntry")).hasWon; + watch(hasWon, hasWon => { + if (hasWon) { + globalBus.emit("gameWon"); + } + }); + if (settings.unthrottled) { + requestAnimationFrame(update); + } else { + intervalID = setInterval(update, 50); + } +} + +document.fonts.onloadingdone = () => globalBus.emit("fontsLoaded"); diff --git a/src/game/layers.tsx b/src/game/layers.tsx new file mode 100644 index 0000000..404d72c --- /dev/null +++ b/src/game/layers.tsx @@ -0,0 +1,337 @@ +import Modal from "components/Modal.vue"; +import type { + CoercableComponent, + JSXFunction, + OptionsFunc, + Replace, + StyleValue +} from "features/feature"; +import { jsx, setDefault } from "features/feature"; +import { globalBus } from "game/events"; +import type { Persistent } from "game/persistence"; +import { persistent } from "game/persistence"; +import player from "game/player"; +import type { Emitter } from "nanoevents"; +import { createNanoEvents } from "nanoevents"; +import type { + Computable, + GetComputableType, + GetComputableTypeWithDefault, + ProcessedComputable +} from "util/computed"; +import { processComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import type { InjectionKey, Ref } from "vue"; +import { ref, shallowReactive, unref } from "vue"; + +/** A feature's node in the DOM that has its size tracked. */ +export interface FeatureNode { + rect: DOMRect; + observer: MutationObserver; + element: HTMLElement; +} + +/** + * An injection key that a {@link ContextComponent} will use to provide a function that registers a {@link FeatureNode} with the given id and HTML element. + */ +export const RegisterNodeInjectionKey: InjectionKey<(id: string, element: HTMLElement) => void> = + Symbol("RegisterNode"); +/** + * An injection key that a {@link ContextComponent} will use to provide a function that unregisters a {@link FeatureNode} with the given id. + */ +export const UnregisterNodeInjectionKey: InjectionKey<(id: string) => void> = + Symbol("UnregisterNode"); +/** + * An injection key that a {@link ContextComponent} will use to provide a ref to a map of all currently registered {@link FeatureNode}s. + */ +export const NodesInjectionKey: InjectionKey<Ref<Record<string, FeatureNode | undefined>>> = + Symbol("Nodes"); +/** + * An injection key that a {@link ContextComponent} will use to provide a ref to a bounding rect of the Context. + */ +export const BoundsInjectionKey: InjectionKey<Ref<DOMRect | undefined>> = Symbol("Bounds"); + +/** All types of events able to be sent or emitted from a layer's emitter. */ +export interface LayerEvents { + /** + * Sent every game tick, before the update event. Intended for "generation" type actions. + * @param diff The delta time since last tick, in ms. + */ + preUpdate: (diff: number) => void; + /** + * Sent every game tick. Intended for "automation" type actions. + * @param diff The delta time since last tick, in ms. + */ + update: (diff: number) => void; + /** + * Sent every game tick, after the update event. Intended for checking state. + * @param diff The delta time since last tick, in ms. + */ + postUpdate: (diff: number) => void; +} + +/** + * A reference to all the current layers. + * It is shallow reactive so it will update when layers are added or removed, but not interfere with the existing refs within each layer. + */ +export const layers: Record<string, Readonly<GenericLayer> | undefined> = shallowReactive({}); + +declare global { + /** Augment the window object so the layers can be accessed from the console. */ + interface Window { + layers: Record<string, Readonly<GenericLayer> | undefined>; + } +} +window.layers = layers; + +declare module "@vue/runtime-dom" { + /** Augment CSS Properties to allow for setting the layer color CSS variable. */ + interface CSSProperties { + "--layer-color"?: string; + } +} + +/** An object representing the position of some entity. */ +export interface Position { + /** The X component of the entity's position. */ + x: number; + /** The Y component of the entity's position. */ + y: number; +} + +/** + * An object that configures a {@link Layer}. + * Even moreso than features, the developer is expected to include extra properties in this object. + * All {@link game/persistence.Persistent} refs must be included somewhere within the layer object. + */ +export interface LayerOptions { + /** The color of the layer, used to theme the entire layer's display. */ + color?: Computable<string>; + /** + * The layout of this layer's features. + * When the layer is open in {@link game/player.PlayerData.tabs}, this is the content that is display. + */ + display: Computable<CoercableComponent>; + /** An object of classes that should be applied to the display. */ + classes?: Computable<Record<string, boolean>>; + /** Styles that should be applied to the display. */ + style?: Computable<StyleValue>; + /** + * The name of the layer, used on minimized tabs. + * Defaults to {@link BaseLayer.id}. + */ + name?: Computable<string>; + /** + * Whether or not the layer can be minimized. + * Defaults to true. + */ + minimizable?: Computable<boolean>; + /** + * Whether or not to force the go back button to be hidden. + * If true, go back will be hidden regardless of {@link data/projInfo.allowGoBack}. + */ + forceHideGoBack?: Computable<boolean>; + /** + * A CSS min-width value that is applied to the layer. + * Can be a number, in which case the unit is assumed to be px. + * Defaults to 600px. + */ + minWidth?: Computable<number | string>; +} + +/** The properties that are added onto a processed {@link LayerOptions} to create a {@link Layer} */ +export interface BaseLayer { + /** + * The ID of the layer. + * Populated from the {@link createLayer} parameters. + * Used for saving and tracking open tabs. + */ + id: string; + /** A persistent ref tracking if the tab is minimized or not. */ + minimized: Persistent<boolean>; + /** An emitter for sending {@link LayerEvents} events for this layer. */ + emitter: Emitter<LayerEvents>; + /** A function to register an event listener on {@link emitter}. */ + on: OmitThisParameter<Emitter<LayerEvents>["on"]>; + /** A function to emit a {@link LayerEvents} event to this layer. */ + emit: <K extends keyof LayerEvents>(...args: [K, ...Parameters<LayerEvents[K]>]) => void; + /** A map of {@link FeatureNode}s present in this layer's {@link ContextComponent} component. */ + nodes: Ref<Record<string, FeatureNode | undefined>>; +} + +/** An unit of game content. Displayed to the user as a tab or modal. */ +export type Layer<T extends LayerOptions> = Replace< + T & BaseLayer, + { + color: GetComputableType<T["color"]>; + display: GetComputableType<T["display"]>; + classes: GetComputableType<T["classes"]>; + style: GetComputableType<T["style"]>; + name: GetComputableTypeWithDefault<T["name"], string>; + minWidth: GetComputableTypeWithDefault<T["minWidth"], 600>; + minimizable: GetComputableTypeWithDefault<T["minimizable"], true>; + forceHideGoBack: GetComputableType<T["forceHideGoBack"]>; + } +>; + +/** A type that matches any valid {@link Layer} object. */ +export type GenericLayer = Replace< + Layer<LayerOptions>, + { + name: ProcessedComputable<string>; + minWidth: ProcessedComputable<number>; + minimizable: ProcessedComputable<boolean>; + } +>; + +/** + * When creating layers, this object a map of layer ID to a set of any created persistent refs in order to check they're all included in the final layer object. + */ +export const persistentRefs: Record<string, Set<Persistent>> = {}; +/** + * When creating layers, this array stores the layers currently being created, as a stack. + */ +export const addingLayers: string[] = []; +/** + * Lazily creates a layer with the given options. + * @param id The ID this layer will have. See {@link BaseLayer.id}. + * @param optionsFunc Layer options. + */ +export function createLayer<T extends LayerOptions>( + id: string, + optionsFunc: OptionsFunc<T, BaseLayer> +): Layer<T> { + return createLazyProxy(() => { + const layer = {} as T & Partial<BaseLayer>; + const emitter = (layer.emitter = createNanoEvents<LayerEvents>()); + layer.on = emitter.on.bind(emitter); + layer.emit = emitter.emit.bind(emitter) as <K extends keyof LayerEvents>( + ...args: [K, ...Parameters<LayerEvents[K]>] + ) => void; + layer.nodes = ref({}); + layer.id = id; + + addingLayers.push(id); + persistentRefs[id] = new Set(); + layer.minimized = persistent(false); + Object.assign(layer, optionsFunc.call(layer as BaseLayer)); + if ( + addingLayers[addingLayers.length - 1] == null || + addingLayers[addingLayers.length - 1] !== id + ) { + throw `Adding layers stack in invalid state. This should not happen\nStack: ${addingLayers}\nTrying to pop ${layer.id}`; + } + addingLayers.pop(); + + processComputable(layer as T, "color"); + processComputable(layer as T, "display"); + processComputable(layer as T, "name"); + setDefault(layer, "name", layer.id); + processComputable(layer as T, "minWidth"); + setDefault(layer, "minWidth", 600); + processComputable(layer as T, "minimizable"); + setDefault(layer, "minimizable", true); + + return layer as unknown as Layer<T>; + }); +} + +/** + * Enables a layer object, so it will be updated every tick. + * Note that accessing a layer/its properties does NOT require it to be enabled. + * For dynamic layers you can call this function and {@link removeLayer} as necessary. Just make sure {@link data/projEntry.getInitialLayers} will provide an accurate list of layers based on the player data object. + * For static layers just make {@link data/projEntry.getInitialLayers} return all the layers. + * @param layer The layer to add. + * @param player The player data object, which will have a data object for this layer. + */ +export function addLayer( + layer: GenericLayer, + player: { layers?: Record<string, Record<string, unknown>> } +): void { + console.info("Adding layer", layer.id); + if (layers[layer.id]) { + console.error( + "Attempted to add layer with same ID as existing layer", + layer.id, + layers[layer.id] + ); + return; + } + + setDefault(player, "layers", {}); + if (player.layers[layer.id] == null) { + player.layers[layer.id] = {}; + } + layers[layer.id] = layer; + + globalBus.emit("addLayer", layer, player.layers[layer.id]); +} + +/** + * Convenience method for getting a layer by its ID with correct typing. + * @param layerID The ID of the layer to get. + */ +export function getLayer<T extends GenericLayer>(layerID: string): T { + return layers[layerID] as T; +} + +/** + * Disables a layer, so it will no longer be updated every tick. + * Note that accessing a layer/its properties does NOT require it to be enabled. + * @param layer The layer to remove. + */ +export function removeLayer(layer: GenericLayer): void { + console.info("Removing layer", layer.id); + globalBus.emit("removeLayer", layer); + + layers[layer.id] = undefined; +} + +/** + * Convenience method for removing and immediately re-adding a layer. + * This is useful for layers with dynamic content, to ensure persistent refs are correctly configured. + * @param layer Layer to remove and then re-add + */ +export function reloadLayer(layer: GenericLayer): void { + removeLayer(layer); + + // Re-create layer + addLayer(layer, player); +} + +/** + * Utility function for creating a modal that display's a {@link LayerOptions.display}. + * Returns the modal itself, which can be rendered anywhere you need, as well as a function to open the modal. + * @param layer The layer to display in the modal. + */ +export function setupLayerModal(layer: GenericLayer): { + openModal: VoidFunction; + modal: JSXFunction; +} { + const showModal = ref(false); + return { + openModal: () => (showModal.value = true), + modal: jsx(() => ( + <Modal + modelValue={showModal.value} + onUpdate:modelValue={value => (showModal.value = value)} + v-slots={{ + header: () => <h2>{unref(layer.name)}</h2>, + body: unref(layer.display) + }} + /> + )) + }; +} + +globalBus.on("update", function updateLayers(diff) { + Object.values(layers).forEach(layer => { + layer?.emit("preUpdate", diff); + }); + Object.values(layers).forEach(layer => { + layer?.emit("update", diff); + }); + Object.values(layers).forEach(layer => { + layer?.emit("postUpdate", diff); + }); +}); diff --git a/src/game/modifiers.tsx b/src/game/modifiers.tsx new file mode 100644 index 0000000..e6e5f66 --- /dev/null +++ b/src/game/modifiers.tsx @@ -0,0 +1,294 @@ +import "components/common/modifiers.css"; +import type { CoercableComponent } from "features/feature"; +import { jsx } from "features/feature"; +import type { DecimalSource } from "util/bignum"; +import Decimal, { format } from "util/bignum"; +import type { WithRequired } from "util/common"; +import type { Computable, ProcessedComputable } from "util/computed"; +import { convertComputable } from "util/computed"; +import { createLazyProxy } from "util/proxies"; +import { renderJSX } from "util/vue"; +import { computed, unref } from "vue"; + +/** + * An object that can be used to apply or unapply some modification to a number. + * Being reversible requires the operation being invertible, but some features may rely on that. + * Descriptions can be optionally included for displaying them to the player. + * The built-in modifier creators are designed to display the modifiers using. + * {@link createModifierSection}. + */ +export interface Modifier { + /** Applies some operation on the input and returns the result. */ + apply: (gain: DecimalSource) => DecimalSource; + /** Reverses the operation applied by the apply property. Required by some features. */ + revert?: (gain: DecimalSource) => DecimalSource; + /** + * Whether or not this modifier should be considered enabled. + * Typically for use with modifiers passed into {@link createSequentialModifier}. + */ + enabled?: ProcessedComputable<boolean>; + /** + * A description of this modifier. + * @see {@link createModifierSection}. + */ + description?: ProcessedComputable<CoercableComponent>; +} + +/** + * Utility type used to narrow down a modifier type that will have a description and/or enabled property based on optional parameters, T and S (respectively). + */ +export type ModifierFromOptionalParams<T, S> = T extends undefined + ? S extends undefined + ? Omit<WithRequired<Modifier, "revert">, "description" | "enabled"> + : Omit<WithRequired<Modifier, "revert" | "enabled">, "description"> + : S extends undefined + ? Omit<WithRequired<Modifier, "revert" | "description">, "enabled"> + : WithRequired<Modifier, "revert" | "enabled" | "description">; + +/** An object that configures an additive modifier via {@link createAdditiveModifier}. */ +export interface AdditiveModifierOptions { + /** The amount to add to the input value. */ + addend: Computable<DecimalSource>; + /** Description of what this modifier is doing. */ + description?: Computable<CoercableComponent> | undefined; + /** A computable that will be processed and passed directly into the returned modifier. */ + enabled?: Computable<boolean> | undefined; +} + +/** + * Create a modifier that adds some value to the input value. + * @param optionsFunc Additive modifier options. + */ +export function createAdditiveModifier<T extends AdditiveModifierOptions>( + optionsFunc: () => T +): ModifierFromOptionalParams<T["description"], T["enabled"]> { + return createLazyProxy(() => { + const { addend, description, enabled } = optionsFunc(); + + const processedAddend = convertComputable(addend); + const processedDescription = convertComputable(description); + const processedEnabled = enabled == null ? undefined : convertComputable(enabled); + return { + apply: (gain: DecimalSource) => Decimal.add(gain, unref(processedAddend)), + revert: (gain: DecimalSource) => Decimal.sub(gain, unref(processedAddend)), + enabled: processedEnabled, + description: + description == null + ? undefined + : jsx(() => ( + <div class="modifier-container"> + <span class="modifier-amount"> + {Decimal.gte(unref(processedAddend), 0) ? "+" : ""} + {format(unref(processedAddend))} + </span> + {unref(processedDescription) ? ( + <span class="modifier-description"> + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {renderJSX(unref(processedDescription)!)} + </span> + ) : null} + </div> + )) + }; + }) as unknown as ModifierFromOptionalParams<T["description"], T["enabled"]>; +} + +/** An object that configures an multiplicative modifier via {@link createMultiplicativeModifier}. */ +export interface MultiplicativeModifierOptions { + /** The amount to multiply the input value by. */ + multiplier: Computable<DecimalSource>; + /** Description of what this modifier is doing. */ + description?: Computable<CoercableComponent> | undefined; + /** A computable that will be processed and passed directly into the returned modifier. */ + enabled?: Computable<boolean> | undefined; +} + +/** + * Create a modifier that multiplies the input value by some value. + * @param optionsFunc Multiplicative modifier options. + */ +export function createMultiplicativeModifier<T extends MultiplicativeModifierOptions>( + optionsFunc: () => T +): ModifierFromOptionalParams<T["description"], T["enabled"]> { + return createLazyProxy(() => { + const { multiplier, description, enabled } = optionsFunc(); + + const processedMultiplier = convertComputable(multiplier); + const processedDescription = convertComputable(description); + const processedEnabled = enabled == null ? undefined : convertComputable(enabled); + return { + apply: (gain: DecimalSource) => Decimal.times(gain, unref(processedMultiplier)), + revert: (gain: DecimalSource) => Decimal.div(gain, unref(processedMultiplier)), + enabled: processedEnabled, + description: + description == null + ? undefined + : jsx(() => ( + <div class="modifier-container"> + <span class="modifier-amount"> + x{format(unref(processedMultiplier))} + </span> + {unref(processedDescription) ? ( + <span class="modifier-description"> + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {renderJSX(unref(processedDescription)!)} + </span> + ) : null} + </div> + )) + }; + }) as unknown as ModifierFromOptionalParams<T["description"], T["enabled"]>; +} + +/** An object that configures an exponential modifier via {@link createExponentialModifier}. */ +export interface ExponentialModifierOptions { + /** The amount to raise the input value to the power of. */ + exponent: Computable<DecimalSource>; + /** Description of what this modifier is doing. */ + description?: Computable<CoercableComponent> | undefined; + /** A computable that will be processed and passed directly into the returned modifier. */ + enabled?: Computable<boolean> | undefined; + /** Add 1 before calculating, then remove it afterwards. This prevents low numbers from becoming lower. */ + supportLowNumbers?: boolean; +} + +/** + * Create a modifier that raises the input value to the power of some value. + * @param optionsFunc Exponential modifier options. + */ +export function createExponentialModifier<T extends ExponentialModifierOptions>( + optionsFunc: () => T +): ModifierFromOptionalParams<T["description"], T["enabled"]> { + return createLazyProxy(() => { + const { exponent, description, enabled, supportLowNumbers } = optionsFunc(); + + const processedExponent = convertComputable(exponent); + const processedDescription = convertComputable(description); + const processedEnabled = enabled == null ? undefined : convertComputable(enabled); + return { + apply: (gain: DecimalSource) => { + let result = gain; + if (supportLowNumbers) { + result = Decimal.add(result, 1); + } + result = Decimal.pow(result, unref(processedExponent)); + if (supportLowNumbers) { + result = Decimal.sub(result, 1); + } + return result; + }, + revert: (gain: DecimalSource) => { + let result = gain; + if (supportLowNumbers) { + result = Decimal.add(result, 1); + } + result = Decimal.root(result, unref(processedExponent)); + if (supportLowNumbers) { + result = Decimal.sub(result, 1); + } + return result; + }, + enabled: processedEnabled, + description: + description == null + ? undefined + : jsx(() => ( + <div class="modifier-container"> + <span class="modifier-amount"> + ^{format(unref(processedExponent))} + </span> + {unref(processedDescription) ? ( + <span class="modifier-description"> + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {renderJSX(unref(processedDescription)!)} + {supportLowNumbers ? " (+1 effective)" : null} + </span> + ) : null} + </div> + )) + }; + }) as unknown as ModifierFromOptionalParams<T["description"], T["enabled"]>; +} + +/** + * Takes an array of modifiers and applies and reverses them in order. + * Modifiers that are not enabled will not be applied nor reversed. + * Also joins their descriptions together. + * @param modifiersFunc The modifiers to perform sequentially. + * @see {@link createModifierSection}. + */ +export function createSequentialModifier< + T extends Modifier[], + S = T extends WithRequired<Modifier, "revert">[] + ? WithRequired<Modifier, "description" | "revert"> + : Omit<WithRequired<Modifier, "description">, "revert"> +>(modifiersFunc: () => T): S { + return createLazyProxy(() => { + const modifiers = modifiersFunc(); + + return { + apply: (gain: DecimalSource) => + modifiers + .filter(m => unref(m.enabled) !== false) + .reduce((gain, modifier) => modifier.apply(gain), gain), + revert: modifiers.every(m => m.revert != null) + ? (gain: DecimalSource) => + modifiers + .filter(m => unref(m.enabled) !== false) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + .reduceRight((gain, modifier) => modifier.revert!(gain), gain) + : undefined, + enabled: computed(() => modifiers.filter(m => unref(m.enabled) !== false).length > 0), + description: jsx(() => ( + <> + {( + modifiers + .filter(m => unref(m.enabled) !== false) + .map(m => unref(m.description)) + .filter(d => d) as CoercableComponent[] + ).map(renderJSX)} + </> + )) + }; + }) as unknown as S; +} + +/** + * Create a JSX element that displays a modifier. + * Intended to be used with the output from {@link createSequentialModifier}. + * @param title The header for the section. + * @param subtitle Smaller text that appears in the header after the title. + * @param modifier The modifier to render. + * @param base The base value that'll be passed into the modifier. + * @param unit The unit of the value being modified, if any. + * @param baseText The label to use for the base value. + */ +export function createModifierSection( + title: string, + subtitle: string, + modifier: WithRequired<Modifier, "description">, + base: DecimalSource = 1, + unit = "", + baseText: CoercableComponent = "Base" +) { + return ( + <div> + <h3> + {title} + {subtitle ? <span class="subtitle"> ({subtitle})</span> : null} + </h3> + <br /> + <div class="modifier-container"> + <span class="modifier-amount"> + {format(base)} + {unit} + </span> + <span class="modifier-description">{renderJSX(baseText)}</span> + </div> + {renderJSX(unref(modifier.description))} + <hr /> + Total: {format(modifier.apply(base))} + {unit} + </div> + ); +} diff --git a/src/game/notifications.ts b/src/game/notifications.ts new file mode 100644 index 0000000..5a43c1a --- /dev/null +++ b/src/game/notifications.ts @@ -0,0 +1,55 @@ +import { globalBus } from "game/events"; +import { convertComputable } from "util/computed"; +import { trackHover, VueFeature } from "util/vue"; +import { nextTick, Ref } from "vue"; +import { ref, watch } from "vue"; +import Toast from "vue-toastification"; +import "vue-toastification/dist/index.css"; + +globalBus.on("setupVue", vue => vue.use(Toast)); + +/** + * Gives a {@link CSSProperties} object that makes an object glow, to bring focus to it. + * Default values are for a "soft" white notif effect. + * @param color The color of the glow effect. + * @param strength The strength of the glow effect - affects its spread. + */ +export function getNotifyStyle(color = "white", strength = "8px") { + return { + transform: "scale(1.05, 1.05)", + borderColor: "rgba(0, 0, 0, 0.125)", + boxShadow: `-4px -4px 4px rgba(0, 0, 0, 0.25) inset, 0 0 ${strength} ${color}`, + zIndex: 1 + }; +} + +/** Utility function to call {@link getNotifyStyle} with "high importance" parameters. */ +export function getHighNotifyStyle() { + return getNotifyStyle("red", "20px"); +} + +/** + * Create a boolean ref that will automatically be set based on the given condition, but also dismissed when hovering over a given element, typically the element where acting upon the notification would take place. + * @param element The element that will dismiss the notification on hover. + * @param shouldNotify A function or ref that determines if the notif should be active currently or not. + */ +export function createDismissableNotify( + element: VueFeature, + shouldNotify: Ref<boolean> | (() => boolean) +): Ref<boolean> { + const processedShouldNotify = convertComputable(shouldNotify) as Ref<boolean>; + const notifying = ref(false); + nextTick(() => { + notifying.value = processedShouldNotify.value; + + watch(trackHover(element), hovering => { + if (!hovering) { + notifying.value = false; + } + }); + watch(processedShouldNotify, shouldNotify => { + notifying.value = shouldNotify; + }); + }); + return notifying; +} diff --git a/src/game/persistence.ts b/src/game/persistence.ts new file mode 100644 index 0000000..b871fbf --- /dev/null +++ b/src/game/persistence.ts @@ -0,0 +1,212 @@ +import { isArray } from "@vue/shared"; +import { globalBus } from "game/events"; +import type { GenericLayer } from "game/layers"; +import { addingLayers, persistentRefs } from "game/layers"; +import type { DecimalSource } from "util/bignum"; +import Decimal from "util/bignum"; +import { ProxyState } from "util/proxies"; +import type { Ref } from "vue"; +import { isReactive, isRef, ref } from "vue"; + +/** + * A symbol used in {@link Persistent} objects. + * @see {@link Persistent[PersistentState]} + */ +export const PersistentState = Symbol("PersistentState"); +/** + * A symbol used in {@link Persistent} objects. + * @see {@link Persistent[DefaultValue]} + */ +export const DefaultValue = Symbol("DefaultValue"); +/** + * A symbol used in {@link Persistent} objects. + * @see {@link Persistent[StackTrace]} + */ +export const StackTrace = Symbol("StackTrace"); +/** + * A symbol used in {@link Persistent} objects. + * @see {@link Persistent[Deleted]} + */ +export const Deleted = Symbol("Deleted"); + +/** + * This is a union of things that should be safely stringifiable without needing special processes or knowing what to load them in as. + * - Decimals aren't allowed because we'd need to know to parse them back. + * - DecimalSources are allowed because the string is a valid value for them + */ +export type State = + | string + | number + | boolean + | DecimalSource + | { [key: string]: State } + | { [key: number]: State }; + +/** + * A {@link Ref} that has been augmented with properties to allow it to be saved and loaded within the player save data object. + */ +export type Persistent<T extends State = State> = Ref<T> & { + /** A flag that this is a persistent property. Typically a circular reference. */ + [PersistentState]: Ref<T>; + /** The value the ref should be set to in a fresh save, or when updating an old save to the current version. */ + [DefaultValue]: T; + /** The stack trace of where the persistent ref was created. This is used for debugging purposes when a persistent ref is created but not placed in its layer object. */ + [StackTrace]: string; + /** + * This is a flag that can be set once the option func is evaluated, to mark that a persistent ref should _not_ be saved to the player save data object. + * @see {@link deletePersistent} for marking a persistent ref as deleted. + */ + [Deleted]: boolean; +}; + +function getStackTrace() { + return ( + new Error().stack + ?.split("\n") + .slice(3, 5) + .map(line => line.trim()) + .join("\n") || "" + ); +} + +/** + * Create a persistent ref, which can be saved and loaded. + * All (non-deleted) persistent refs must be included somewhere within the layer object returned by that layer's options func. + * @param defaultValue The value the persistent ref should start at on fresh saves or when reset. + */ +export function persistent<T extends State>(defaultValue: T | Ref<T>): Persistent<T> { + const persistent = ( + isRef(defaultValue) ? defaultValue : (ref<T>(defaultValue) as unknown) + ) as Persistent<T>; + + persistent[PersistentState] = persistent; + persistent[DefaultValue] = isRef(defaultValue) ? defaultValue.value : defaultValue; + persistent[StackTrace] = getStackTrace(); + persistent[Deleted] = false; + + if (addingLayers.length === 0) { + console.warn( + "Creating a persistent ref outside of a layer. This is not officially supported", + persistent, + "\nCreated at:\n" + persistent[StackTrace] + ); + } else { + persistentRefs[addingLayers[addingLayers.length - 1]].add(persistent); + } + + return persistent as Persistent<T>; +} + +/** + * Mark a {@link Persistent} as deleted, so it won't be saved and loaded. + * Since persistent refs must be created during a layer's options func, features can not create persistent refs after evaluating their own options funcs. + * As a result, it must create any persistent refs it _might_ need. + * This function can then be called after the options func is evaluated to mark the persistent ref to not be saved or loaded. + */ +export function deletePersistent(persistent: Persistent) { + if (addingLayers.length === 0) { + console.warn("Deleting a persistent ref outside of a layer. Ignoring...", persistent); + } else { + persistentRefs[addingLayers[addingLayers.length - 1]].delete(persistent); + } + persistent[Deleted] = true; +} + +globalBus.on("addLayer", (layer: GenericLayer, saveData: Record<string, unknown>) => { + const features: { type: typeof Symbol }[] = []; + const handleObject = (obj: Record<string, unknown>, path: string[] = []): boolean => { + let foundPersistent = false; + Object.keys(obj).forEach(key => { + const value = obj[key]; + if (value && typeof value === "object") { + if (PersistentState in value) { + foundPersistent = true; + if ((value as Persistent)[Deleted]) { + console.warn( + "Deleted persistent ref present in returned object. Ignoring...", + value, + "\nCreated at:\n" + (value as Persistent)[StackTrace] + ); + return; + } + persistentRefs[layer.id].delete( + ProxyState in value + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + ((value as any)[ProxyState] as Persistent) + : (value as Persistent) + ); + + // Construct save path if it doesn't exist + const persistentState = path.reduce<Record<string, unknown>>((acc, curr) => { + if (!(curr in acc)) { + acc[curr] = {}; + } + return acc[curr] as Record<string, unknown>; + }, saveData); + + // Cache currently saved value + const savedValue = persistentState[key]; + // Add ref to save data + persistentState[key] = (value as Persistent)[PersistentState]; + // Load previously saved value + if (isReactive(persistentState)) { + if (savedValue != null) { + persistentState[key] = savedValue; + } else { + persistentState[key] = (value as Persistent)[DefaultValue]; + } + } else { + if (savedValue != null) { + (persistentState[key] as Ref<unknown>).value = savedValue; + } else { + (persistentState[key] as Ref<unknown>).value = (value as Persistent)[ + DefaultValue + ]; + } + } + } else if ( + !(value instanceof Decimal) && + !isRef(value) && + // eslint-disable-next-line @typescript-eslint/no-explicit-any + !features.includes(value as { type: typeof Symbol }) + ) { + if (typeof (value as { type: typeof Symbol }).type === "symbol") { + features.push(value as { type: typeof Symbol }); + } + + // Continue traversing + const foundPersistentInChild = handleObject(value as Record<string, unknown>, [ + ...path, + key + ]); + + // Show warning for persistent values inside arrays + // TODO handle arrays better + if (foundPersistentInChild) { + if (isArray(value) && !isArray(obj)) { + console.warn( + "Found array that contains persistent values when adding layer. Keep in mind changing the order of elements in the array will mess with existing player saves.", + ProxyState in obj + ? (obj as Record<PropertyKey, unknown>)[ProxyState] + : obj, + key + ); + } else { + foundPersistent = true; + } + } + } + } + }); + return foundPersistent; + }; + handleObject(layer); + persistentRefs[layer.id].forEach(persistent => { + console.error( + `Created persistent ref in ${layer.id} without registering it to the layer! Make sure to include everything persistent in the returned object`, + persistent, + "\nCreated at:\n" + persistent[StackTrace] + ); + }); + persistentRefs[layer.id].clear(); +}); diff --git a/src/game/player.ts b/src/game/player.ts new file mode 100644 index 0000000..6271629 --- /dev/null +++ b/src/game/player.ts @@ -0,0 +1,157 @@ +import { isPlainObject } from "is-plain-object"; +import Decimal from "util/bignum"; +import type { ProxiedWithState } from "util/proxies"; +import { ProxyPath, ProxyState } from "util/proxies"; +import { reactive, unref } from "vue"; +import type { Ref } from "vue"; +import transientState from "./state"; + +/** The player save data object. */ +export interface PlayerData { + /** The ID of this save. */ + id: string; + /** A multiplier for time passing. Set to 0 when the game is paused. */ + devSpeed: number | null; + /** The display name of this save. */ + name: string; + /** The open tabs. */ + tabs: Array<string>; + /** The current time this save was last opened at, in ms since the unix epoch. */ + time: number; + /** Whether or not to automatically save every couple of seconds and on tab close. */ + autosave: boolean; + /** Whether or not to apply offline time when loading this save. */ + offlineProd: boolean; + /** How much offline time has been accumulated and not yet processed. */ + offlineTime: number | null; + /** How long, in ms, this game has been played. */ + timePlayed: number; + /** Whether or not to continue playing after {@link data/projEntry.hasWon} is true. */ + keepGoing: boolean; + /** The ID of this project, to make sure saves aren't imported into the wrong project. */ + modID: string; + /** The version of the project this save was created by. Used for upgrading saves for new versions. */ + modVersion: string; + /** A dictionary of layer save data. */ + layers: Record<string, LayerData<unknown>>; +} + +/** The proxied player that is used to track NaN values. */ +export type Player = ProxiedWithState<PlayerData>; + +/** A layer's save data. Automatically unwraps refs. */ +export type LayerData<T> = { + [P in keyof T]?: T[P] extends (infer U)[] + ? Record<string, LayerData<U>> + : T[P] extends Record<string, never> + ? never + : T[P] extends Ref<infer S> + ? S + : T[P] extends object + ? LayerData<T[P]> + : T[P]; +}; + +const state = reactive<PlayerData>({ + id: "", + devSpeed: null, + name: "", + tabs: [], + time: -1, + autosave: true, + offlineProd: true, + offlineTime: null, + timePlayed: 0, + keepGoing: false, + modID: "", + modVersion: "", + layers: {} +}); + +/** Convert a player save data object into a JSON string. Unwraps refs. */ +export function stringifySave(player: PlayerData): string { + return JSON.stringify(player, (key, value) => unref(value)); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const playerHandler: ProxyHandler<Record<PropertyKey, any>> = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + get(target: Record<PropertyKey, any>, key: PropertyKey): any { + if (key === ProxyState || key === ProxyPath) { + return target[key]; + } + + const value = target[ProxyState][key]; + if (key !== "value" && (isPlainObject(value) || Array.isArray(value))) { + if (value !== target[key]?.[ProxyState]) { + const path = [...target[ProxyPath], key]; + target[key] = new Proxy({ [ProxyState]: value, [ProxyPath]: path }, playerHandler); + } + return target[key]; + } + + return value; + }, + set( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + target: Record<PropertyKey, any>, + property: PropertyKey, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: any, + receiver: ProxyConstructor + ): boolean { + if ( + !transientState.hasNaN && + ((typeof value === "number" && isNaN(value)) || + (value instanceof Decimal && + (isNaN(value.sign) || isNaN(value.layer) || isNaN(value.mag)))) + ) { + const currentValue = target[ProxyState][property]; + if ( + !( + (typeof currentValue === "number" && isNaN(currentValue)) || + (currentValue instanceof Decimal && + (isNaN(currentValue.sign) || + isNaN(currentValue.layer) || + isNaN(currentValue.mag))) + ) + ) { + state.autosave = false; + transientState.hasNaN = true; + transientState.NaNPath = [...target[ProxyPath], property]; + transientState.NaNReceiver = receiver as unknown as Record<string, unknown>; + console.error( + `Attempted to set NaN value`, + [...target[ProxyPath], property], + target[ProxyState] + ); + throw "Attempted to set NaN value. See above for details"; + } + } + target[ProxyState][property] = value; + return true; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ownKeys(target: Record<PropertyKey, any>) { + return Reflect.ownKeys(target[ProxyState]); + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + has(target: Record<PropertyKey, any>, key: string) { + return Reflect.has(target[ProxyState], key); + }, + getOwnPropertyDescriptor(target, key) { + return Object.getOwnPropertyDescriptor(target[ProxyState], key); + } +}; + +declare global { + /** Augment the window object so the player can be accessed from the console. */ + interface Window { + player: Player; + } +} +/** The player save data object. */ +export default window.player = new Proxy( + { [ProxyState]: state, [ProxyPath]: ["player"] }, + playerHandler +) as Player; diff --git a/src/game/settings.ts b/src/game/settings.ts new file mode 100644 index 0000000..cad4438 --- /dev/null +++ b/src/game/settings.ts @@ -0,0 +1,119 @@ +import projInfo from "data/projInfo.json"; +import { Themes } from "data/themes"; +import type { CoercableComponent } from "features/feature"; +import { globalBus } from "game/events"; +import LZString from "lz-string"; +import { hardReset } from "util/save"; +import { reactive, watch } from "vue"; + +/** The player's settings object. */ +export interface Settings { + /** The ID of the active save. */ + active: string; + /** The IDs of all created saves. */ + saves: string[]; + /** Whether or not to show the current ticks per second in the lower left corner of the page. */ + showTPS: boolean; + /** The current theme to display the game in. */ + theme: Themes; + /** Whether or not to cap the project at 20 ticks per second. */ + unthrottled: boolean; +} + +const state = reactive<Partial<Settings>>({ + active: "", + saves: [], + showTPS: true, + theme: Themes.Nordic, + unthrottled: false +}); + +watch( + state, + state => { + const stringifiedSettings = LZString.compressToUTF16(JSON.stringify(state)); + localStorage.setItem(projInfo.id, stringifiedSettings); + }, + { deep: true } +); + +declare global { + /** + * Augment the window object so the settings, and hard resetting the settings, can be accessed from the console. + */ + interface Window { + settings: Settings; + hardResetSettings: VoidFunction; + } +} +/** + * The player settings object. Stores data that persists across all saves. + * Automatically saved to localStorage whenever changed. + */ +export default window.settings = state as Settings; +/** A function that erases all player settings, including all saves. */ +export const hardResetSettings = (window.hardResetSettings = () => { + const settings = { + active: "", + saves: [], + showTPS: true, + theme: Themes.Nordic + }; + globalBus.emit("loadSettings", settings); + Object.assign(state, settings); + hardReset(); +}); + +/** + * Loads the player settings from localStorage. + * Calls the {@link GlobalEvents.loadSettings} event for custom properties to be included. + * Custom properties should be added by the file they relate to, so they won't be included if the file is tree shaken away. + * Custom properties should also register the field to modify said setting using {@link registerSettingField}. + */ +export function loadSettings(): void { + try { + let item: string | null = localStorage.getItem(projInfo.id); + if (item != null && item !== "") { + if (item[0] === "{") { + // plaintext. No processing needed + } else if (item[0] === "e") { + // Assumed to be base64, which starts with e + item = decodeURIComponent(escape(atob(item))); + } else if (item[0] === "ᯡ") { + // Assumed to be lz, which starts with ᯡ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + item = LZString.decompressFromUTF16(item)!; + } else { + console.warn("Unable to determine settings encoding", item); + return; + } + const settings = JSON.parse(item); + if (typeof settings === "object") { + Object.assign(state, settings); + } + } + globalBus.emit("loadSettings", state); + // eslint-disable-next-line no-empty + } catch {} +} + +/** A list of fields to append to the settings modal. */ +export const settingFields: CoercableComponent[] = reactive([]); +/** Register a field to be displayed in the settings modal. */ +export function registerSettingField(component: CoercableComponent) { + settingFields.push(component); +} + +/** A list of components to show in the info modal. */ +export const infoComponents: CoercableComponent[] = reactive([]); +/** Register a component to be displayed in the info modal. */ +export function registerInfoComponent(component: CoercableComponent) { + infoComponents.push(component); +} + +/** A list of components to add to the root of the page. */ +export const gameComponents: CoercableComponent[] = reactive([]); +/** Register a component to be displayed at the root of the page. */ +export function registerGameComponent(component: CoercableComponent) { + gameComponents.push(component); +} diff --git a/src/game/state.ts b/src/game/state.ts new file mode 100644 index 0000000..bda0b6a --- /dev/null +++ b/src/game/state.ts @@ -0,0 +1,26 @@ +import { shallowReactive } from "vue"; + +/** An object of global data that is not persistent. */ +export interface Transient { + /** A list of the duration, in ms, of the last 10 game ticks. Used for calculating TPS. */ + lastTenTicks: number[]; + /** Whether or not a NaN value has been detected and undealt with. */ + hasNaN: boolean; + /** The location within the player save data object of the NaN value. */ + NaNPath?: string[]; + /** The parent object of the NaN value. */ + NaNReceiver?: Record<string, unknown>; +} + +declare global { + /** Augment the window object so the transient state can be accessed from the console. */ + interface Window { + state: Transient; + } +} +/** The global transient state object. */ +export default window.state = shallowReactive<Transient>({ + lastTenTicks: [], + hasNaN: false, + NaNPath: [] +}); diff --git a/src/lib/break_eternity.ts b/src/lib/break_eternity.ts new file mode 100644 index 0000000..e3f61db --- /dev/null +++ b/src/lib/break_eternity.ts @@ -0,0 +1,3151 @@ +/* eslint-disable @typescript-eslint/no-this-alias */ +export type CompareResult = -1 | 0 | 1; + +const MAX_SIGNIFICANT_DIGITS = 17; //Maximum number of digits of precision to assume in Number + +const EXP_LIMIT = 9e15; //If we're ABOVE this value, increase a layer. (9e15 is close to the largest integer that can fit in a Number.) + +const LAYER_DOWN: number = Math.log10(9e15); + +const FIRST_NEG_LAYER = 1 / 9e15; //At layer 0, smaller non-zero numbers than this become layer 1 numbers with negative mag. After that the pattern continues as normal. + +const NUMBER_EXP_MAX = 308; //The largest exponent that can appear in a Number, though not all mantissas are valid here. + +const NUMBER_EXP_MIN = -324; //The smallest exponent that can appear in a Number, though not all mantissas are valid here. + +const MAX_ES_IN_A_ROW = 5; //For default toString behaviour, when to swap from eee... to (e^n) syntax. + +const IGNORE_COMMAS = true; +const COMMAS_ARE_DECIMAL_POINTS = false; + +const powerOf10 = (function() { + // We need this lookup table because Math.pow(10, exponent) + // when exponent's absolute value is large is slightly inaccurate. + // You can fix it with the power of math... or just make a lookup table. + // Faster AND simpler + const powersOf10: number[] = []; + + for (let i = NUMBER_EXP_MIN + 1; i <= NUMBER_EXP_MAX; i++) { + powersOf10.push(Number("1e" + i)); + } + + const indexOf0InPowersOf10 = 323; + return function(power: number) { + return powersOf10[power + indexOf0InPowersOf10]; + }; +})(); + +//tetration/slog to real height stuff +//background info and tables of values for critical functions taken here: https://github.com/Patashu/break_eternity.js/issues/22 +const critical_headers = [2, Math.E, 3, 4, 5, 6, 7, 8, 9, 10]; +const critical_tetr_values = [ + [ + // Base 2 + 1, + 1.0891168053867777, + 1.1789745164521264, + 1.2701428397304229, + 1.3632066654400328, + 1.4587804913784246, + 1.557523817412741, + 1.660158301473385, + 1.767487542936873, + 1.8804205225512542, + 2 + ], + [ + // Base E + 1, //0.0 + 1.1121114330934, //0.1 + 1.23103892493161, //0.2 + 1.35838369631113, //0.3 + 1.49605193039935, //0.4 + 1.64635423375119, //0.5 + 1.81213853570186, //0.6 + 1.99697132461829, //0.7 + 2.20538955455724, //0.8 + 2.44325744833852, //0.9 + Math.E //1.0 + ], + [ + // Base 3 + 1, + 1.1187738849693603, + 1.2464963939368214, + 1.38527004705667, + 1.5376664685821402, + 1.7068895236551784, + 1.897001227148399, + 2.1132403089001035, + 2.362480153784171, + 2.6539010333870774, + 3 + ], + [ + // Base 4 + 1, + 1.1367350847096405, + 1.2889510672956703, + 1.4606478703324786, + 1.6570295196661111, + 1.8850062585672889, + 2.1539465047453485, + 2.476829779693097, + 2.872061932789197, + 3.3664204535587183, + 4 + ], + [ + // Base 5 + 1, + 1.1494592900767588, + 1.319708228183931, + 1.5166291280087583, + 1.748171114438024, + 2.0253263297298045, + 2.3636668498288547, + 2.7858359149579424, + 3.3257226212448145, + 4.035730287722532, + 5 + ], + [ + // Base 6 + 1, + 1.159225940787673, + 1.343712473580932, + 1.5611293155111927, + 1.8221199554561318, + 2.14183924486326, + 2.542468319282638, + 3.0574682501653316, + 3.7390572020926873, + 4.6719550537360774, + 6 + ], + [ + // Base 7 + 1, + 1.1670905356972596, + 1.3632807444991446, + 1.5979222279405536, + 1.8842640123816674, + 2.2416069644878687, + 2.69893426559423, + 3.3012632110403577, + 4.121250340630164, + 5.281493033448316, + 7 + ], + [ + // Base 8 + 1, + 1.1736630594087796, + 1.379783782386201, + 1.6292821855668218, + 1.9378971836180754, + 2.3289975651071977, + 2.8384347394720835, + 3.5232708454565906, + 4.478242031114584, + 5.868592169644505, + 8 + ], + [ + // Base 9 + 1, + 1.1793017514670474, + 1.394054150657457, + 1.65664127441059, + 1.985170999970283, + 2.4069682290577457, + 2.9647310119960752, + 3.7278665320924946, + 4.814462547283592, + 6.436522247411611, + 9 + ], + [ + // Base 10 + 1, + 1.18422737399915, + 1.4066113788546144, + 1.680911177655277, + 2.027492094355525, + 2.4775152854601967, + 3.080455730250329, + 3.918234505962507, + 5.1332705696484595, + 6.9878696918072905, + 10 + ] +]; +const critical_slog_values = [ + [ + // Base 2 + -1, + -0.9194161097107025, + -0.8335625019330468, + -0.7425599821143978, + -0.6466611521029437, + -0.5462617907227869, + -0.4419033816638769, + -0.3342645487554494, + -0.224140440909962, + -0.11241087890006762, + 0 + ], + [ + // Base E + -1, //0.0 + -0.90603157029014, //0.1 + -0.80786507256596, //0.2 + -0.7064666939634, //0.3 + -0.60294836853664, //0.4 + -0.49849837513117, //0.5 + -0.39430303318768, //0.6 + -0.29147201034755, //0.7 + -0.19097820800866, //0.8 + -0.09361896280296, //0.9 + 0 //1.0 + ], + [ + // Base 3 + -1, + -0.9021579584316141, + -0.8005762598234203, + -0.6964780623319391, + -0.5911906810998454, + -0.486050182576545, + -0.3823089430815083, + -0.28106046722897615, + -0.1831906535795894, + -0.08935809204418144, + 0 + ], + [ + // Base 4 + -1, + -0.8917227442365535, + -0.781258746326964, + -0.6705130326902455, + -0.5612813129406509, + -0.4551067709033134, + -0.35319256652135966, + -0.2563741554088552, + -0.1651412821106526, + -0.0796919581982668, + 0 + ], + [ + // Base 5 + -1, + -0.8843387974366064, + -0.7678744063886243, + -0.6529563724510552, + -0.5415870994657841, + -0.4352842206588936, + -0.33504449124791424, + -0.24138853420685147, + -0.15445285440944467, + -0.07409659641336663, + 0 + ], + [ + // Base 6 + -1, + -0.8786709358426346, + -0.7577735191184886, + -0.6399546189952064, + -0.527284921869926, + -0.4211627631006314, + -0.3223479611761232, + -0.23107655627789858, + -0.1472057700818259, + -0.07035171210706326, + 0 + ], + [ + // Base 7 + -1, + -0.8740862815291583, + -0.7497032990976209, + -0.6297119746181752, + -0.5161838335958787, + -0.41036238255751956, + -0.31277212146489963, + -0.2233976621705518, + -0.1418697367979619, + -0.06762117662323441, + 0 + ], + [ + // Base 8 + -1, + -0.8702632331800649, + -0.7430366914122081, + -0.6213373075161548, + -0.5072025698095242, + -0.40171437727184167, + -0.30517930701410456, + -0.21736343968190863, + -0.137710238299109, + -0.06550774483471955, + 0 + ], + [ + // Base 9 + -1, + -0.8670016295947213, + -0.7373984232432306, + -0.6143173985094293, + -0.49973884395492807, + -0.394584953527678, + -0.2989649949848695, + -0.21245647317021688, + -0.13434688362382652, + -0.0638072667348083, + 0 + ], + [ + // Base 10 + -1, + -0.8641642839543857, + -0.732534623168535, + -0.6083127477059322, + -0.4934049257184696, + -0.3885773075899922, + -0.29376029055315767, + -0.2083678561173622, + -0.13155653399373268, + -0.062401588652553186, + 0 + ] +]; + +const D = function D(value: DecimalSource): Decimal { + return Decimal.fromValue_noAlloc(value); +}; + +const FC = function(sign: number, layer: number, mag: number) { + return Decimal.fromComponents(sign, layer, mag); +}; + +const FC_NN = function FC_NN(sign: number, layer: number, mag: number) { + return Decimal.fromComponents_noNormalize(sign, layer, mag); +}; + +const ME = function ME(mantissa: number, exponent: number) { + return Decimal.fromMantissaExponent(mantissa, exponent); +}; + +const ME_NN = function ME_NN(mantissa: number, exponent: number) { + return Decimal.fromMantissaExponent_noNormalize(mantissa, exponent); +}; + +const decimalPlaces = function decimalPlaces(value: number, places: number): number { + const len = places + 1; + const numDigits = Math.ceil(Math.log10(Math.abs(value))); + const rounded = + Math.round(value * Math.pow(10, len - numDigits)) * Math.pow(10, numDigits - len); + return parseFloat(rounded.toFixed(Math.max(len - numDigits, 0))); +}; + +const f_maglog10 = function(n: number) { + return Math.sign(n) * Math.log10(Math.abs(n)); +}; + +//from HyperCalc source code +const f_gamma = function(n: number) { + if (!isFinite(n)) { + return n; + } + if (n < -50) { + if (n === Math.trunc(n)) { + return Number.NEGATIVE_INFINITY; + } + return 0; + } + + let scal1 = 1; + while (n < 10) { + scal1 = scal1 * n; + ++n; + } + + n -= 1; + let l = 0.9189385332046727; //0.5*Math.log(2*Math.PI) + l = l + (n + 0.5) * Math.log(n); + l = l - n; + const n2 = n * n; + let np = n; + l = l + 1 / (12 * np); + np = np * n2; + l = l + 1 / (360 * np); + np = np * n2; + l = l + 1 / (1260 * np); + np = np * n2; + l = l + 1 / (1680 * np); + np = np * n2; + l = l + 1 / (1188 * np); + np = np * n2; + l = l + 691 / (360360 * np); + np = np * n2; + l = l + 7 / (1092 * np); + np = np * n2; + l = l + 3617 / (122400 * np); + + return Math.exp(l) / scal1; +}; + +const _twopi = 6.2831853071795864769252842; // 2*pi +const _EXPN1 = 0.36787944117144232159553; // exp(-1) +const OMEGA = 0.56714329040978387299997; // W(1, 0) +//from https://math.stackexchange.com/a/465183 +// The evaluation can become inaccurate very close to the branch point +const f_lambertw = function(z: number, tol = 1e-10): number { + let w; + let wn; + + if (!Number.isFinite(z)) { + return z; + } + if (z === 0) { + return z; + } + if (z === 1) { + return OMEGA; + } + + if (z < 10) { + w = 0; + } else { + w = Math.log(z) - Math.log(Math.log(z)); + } + + for (let i = 0; i < 100; ++i) { + wn = (z * Math.exp(-w) + w * w) / (w + 1); + if (Math.abs(wn - w) < tol * Math.abs(wn)) { + return wn; + } else { + w = wn; + } + } + + throw Error(`Iteration failed to converge: ${z.toString()}`); + //return Number.NaN; +}; + +//from https://github.com/scipy/scipy/blob/8dba340293fe20e62e173bdf2c10ae208286692f/scipy/special/lambertw.pxd +// The evaluation can become inaccurate very close to the branch point +// at ``-1/e``. In some corner cases, `lambertw` might currently +// fail to converge, or can end up on the wrong branch. +function d_lambertw(z: Decimal, tol = 1e-10): Decimal { + let w; + let ew, wew, wewz, wn; + + if (!Number.isFinite(z.mag)) { + return z; + } + if (z === Decimal.dZero) { + return z; + } + if (z === Decimal.dOne) { + //Split out this case because the asymptotic series blows up + return D(OMEGA); + } + + const absz = Decimal.abs(z); + //Get an initial guess for Halley's method + w = Decimal.ln(z); + + //Halley's method; see 5.9 in [1] + + for (let i = 0; i < 100; ++i) { + ew = Decimal.exp(-w); + wewz = w.sub(z.mul(ew)); + wn = w.sub( + wewz.div( + w.add(1).sub( + w + .add(2) + .mul(wewz) + .div(Decimal.mul(2, w).add(2)) + ) + ) + ); + if (Decimal.abs(wn.sub(w)).lt(Decimal.abs(wn).mul(tol))) { + return wn; + } else { + w = wn; + } + } + + throw Error(`Iteration failed to converge: ${z.toString()}`); + //return Decimal.dNaN; +} + +export type DecimalSource = Decimal | number | string; + +/** + * The Decimal's value is simply mantissa * 10^exponent. + */ +export default class Decimal { + public static readonly dZero = FC_NN(0, 0, 0); + public static readonly dOne = FC_NN(1, 0, 1); + public static readonly dNegOne = FC_NN(-1, 0, 1); + public static readonly dTwo = FC_NN(1, 0, 2); + public static readonly dTen = FC_NN(1, 0, 10); + public static readonly dNaN = FC_NN(Number.NaN, Number.NaN, Number.NaN); + public static readonly dInf = FC_NN(1, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); + public static readonly dNegInf = FC_NN(-1, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); + public static readonly dNumberMax = FC(1, 0, Number.MAX_VALUE); + public static readonly dNumberMin = FC(1, 0, Number.MIN_VALUE); + + public sign: number = Number.NaN; + public mag: number = Number.NaN; + public layer: number = Number.NaN; + + constructor(value?: DecimalSource) { + if (value instanceof Decimal || (value != null && typeof value === "object" && "sign" in value && "mag" in value && "layer" in value)) { + this.fromDecimal(value); + } else if (typeof value === "number") { + this.fromNumber(value); + } else if (typeof value === "string") { + this.fromString(value); + } else { + this.sign = 0; + this.layer = 0; + this.mag = 0; + } + } + + get m(): number { + if (this.sign === 0) { + return 0; + } else if (this.layer === 0) { + const exp = Math.floor(Math.log10(this.mag)); + //handle special case 5e-324 + let man; + if (this.mag === 5e-324) { + man = 5; + } else { + man = this.mag / powerOf10(exp); + } + return this.sign * man; + } else if (this.layer === 1) { + const residue = this.mag - Math.floor(this.mag); + return this.sign * Math.pow(10, residue); + } else { + //mantissa stops being relevant past 1e9e15 / ee15.954 + return this.sign; + } + } + + set m(value: number) { + if (this.layer <= 2) { + this.fromMantissaExponent(value, this.e); + } else { + //don't even pretend mantissa is meaningful + this.sign = Math.sign(value); + if (this.sign === 0) { + this.layer === 0; + this.exponent === 0; + } + } + } + + get e(): number { + if (this.sign === 0) { + return 0; + } else if (this.layer === 0) { + return Math.floor(Math.log10(this.mag)); + } else if (this.layer === 1) { + return Math.floor(this.mag); + } else if (this.layer === 2) { + return Math.floor(Math.sign(this.mag) * Math.pow(10, Math.abs(this.mag))); + } else { + return this.mag * Number.POSITIVE_INFINITY; + } + } + set e(value: number) { + this.fromMantissaExponent(this.m, value); + } + + get s(): number { + return this.sign; + } + set s(value: number) { + if (value === 0) { + this.sign = 0; + this.layer = 0; + this.mag = 0; + } else { + this.sign = value; + } + } + + // Object.defineProperty(Decimal.prototype, "mantissa", { + get mantissa(): number { + return this.m; + } + + set mantissa(value: number) { + this.m = value; + } + + get exponent(): number { + return this.e; + } + set exponent(value: number) { + this.e = value; + } + + public static fromComponents(sign: number, layer: number, mag: number): Decimal { + return new Decimal().fromComponents(sign, layer, mag); + } + + public static fromComponents_noNormalize(sign: number, layer: number, mag: number): Decimal { + return new Decimal().fromComponents_noNormalize(sign, layer, mag); + } + + public static fromMantissaExponent(mantissa: number, exponent: number): Decimal { + return new Decimal().fromMantissaExponent(mantissa, exponent); + } + + public static fromMantissaExponent_noNormalize(mantissa: number, exponent: number): Decimal { + return new Decimal().fromMantissaExponent_noNormalize(mantissa, exponent); + } + + public static fromDecimal(value: Decimal): Decimal { + return new Decimal().fromDecimal(value); + } + + public static fromNumber(value: number): Decimal { + return new Decimal().fromNumber(value); + } + + public static fromString(value: string): Decimal { + return new Decimal().fromString(value); + } + + public static fromValue(value: DecimalSource): Decimal { + return new Decimal().fromValue(value); + } + + public static fromValue_noAlloc(value: DecimalSource): Decimal { + return value instanceof Decimal ? value : new Decimal(value); + } + + public static abs(value: DecimalSource): Decimal { + return D(value).abs(); + } + + public static neg(value: DecimalSource): Decimal { + return D(value).neg(); + } + + public static negate(value: DecimalSource): Decimal { + return D(value).neg(); + } + + public static negated(value: DecimalSource): Decimal { + return D(value).neg(); + } + + public static sign(value: DecimalSource): number { + return D(value).sign; + } + + public static sgn(value: DecimalSource): number { + return D(value).sign; + } + + public static round(value: DecimalSource): Decimal { + return D(value).round(); + } + + public static floor(value: DecimalSource): Decimal { + return D(value).floor(); + } + + public static ceil(value: DecimalSource): Decimal { + return D(value).ceil(); + } + + public static trunc(value: DecimalSource): Decimal { + return D(value).trunc(); + } + + public static add(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).add(other); + } + + public static plus(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).add(other); + } + + public static sub(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).sub(other); + } + + public static subtract(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).sub(other); + } + + public static minus(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).sub(other); + } + + public static mul(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).mul(other); + } + + public static multiply(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).mul(other); + } + + public static times(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).mul(other); + } + + public static div(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).div(other); + } + + public static divide(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).div(other); + } + + public static recip(value: DecimalSource): Decimal { + return D(value).recip(); + } + + public static reciprocal(value: DecimalSource): Decimal { + return D(value).recip(); + } + + public static reciprocate(value: DecimalSource): Decimal { + return D(value).reciprocate(); + } + + public static cmp(value: DecimalSource, other: DecimalSource): CompareResult { + return D(value).cmp(other); + } + + public static cmpabs(value: DecimalSource, other: DecimalSource): CompareResult { + return D(value).cmpabs(other); + } + + public static compare(value: DecimalSource, other: DecimalSource): CompareResult { + return D(value).cmp(other); + } + + public static isNaN(value: DecimalSource): boolean { + value = D(value); + return isNaN(value.sign) || isNaN(value.layer) || isNaN(value.mag); + } + + public static isFinite(value: DecimalSource): boolean { + value = D(value); + return isFinite(value.sign) && isFinite(value.layer) && isFinite(value.mag); + } + + public static eq(value: DecimalSource, other: DecimalSource): boolean { + return D(value).eq(other); + } + + public static equals(value: DecimalSource, other: DecimalSource): boolean { + return D(value).eq(other); + } + + public static neq(value: DecimalSource, other: DecimalSource): boolean { + return D(value).neq(other); + } + + public static notEquals(value: DecimalSource, other: DecimalSource): boolean { + return D(value).notEquals(other); + } + + public static lt(value: DecimalSource, other: DecimalSource): boolean { + return D(value).lt(other); + } + + public static lte(value: DecimalSource, other: DecimalSource): boolean { + return D(value).lte(other); + } + + public static gt(value: DecimalSource, other: DecimalSource): boolean { + return D(value).gt(other); + } + + public static gte(value: DecimalSource, other: DecimalSource): boolean { + return D(value).gte(other); + } + + public static max(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).max(other); + } + + public static min(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).min(other); + } + + public static minabs(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).minabs(other); + } + + public static maxabs(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).maxabs(other); + } + + public static clamp(value: DecimalSource, min: DecimalSource, max: DecimalSource): Decimal { + return D(value).clamp(min, max); + } + + public static clampMin(value: DecimalSource, min: DecimalSource): Decimal { + return D(value).clampMin(min); + } + + public static clampMax(value: DecimalSource, max: DecimalSource): Decimal { + return D(value).clampMax(max); + } + + public static cmp_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): CompareResult { + return D(value).cmp_tolerance(other, tolerance); + } + + public static compare_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): CompareResult { + return D(value).cmp_tolerance(other, tolerance); + } + + public static eq_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).eq_tolerance(other, tolerance); + } + + public static equals_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).eq_tolerance(other, tolerance); + } + + public static neq_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).neq_tolerance(other, tolerance); + } + + public static notEquals_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).notEquals_tolerance(other, tolerance); + } + + public static lt_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).lt_tolerance(other, tolerance); + } + + public static lte_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).lte_tolerance(other, tolerance); + } + + public static gt_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).gt_tolerance(other, tolerance); + } + + public static gte_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).gte_tolerance(other, tolerance); + } + + public static pLog10(value: DecimalSource): Decimal { + return D(value).pLog10(); + } + + public static absLog10(value: DecimalSource): Decimal { + return D(value).absLog10(); + } + + public static log10(value: DecimalSource): Decimal { + return D(value).log10(); + } + + public static log(value: DecimalSource, base: DecimalSource): Decimal { + return D(value).log(base); + } + + public static log2(value: DecimalSource): Decimal { + return D(value).log2(); + } + + public static ln(value: DecimalSource): Decimal { + return D(value).ln(); + } + + public static logarithm(value: DecimalSource, base: DecimalSource): Decimal { + return D(value).logarithm(base); + } + + public static pow(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).pow(other); + } + + public static pow10(value: DecimalSource): Decimal { + return D(value).pow10(); + } + + public static root(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).root(other); + } + + public static factorial(value: DecimalSource, _other?: never): Decimal { + return D(value).factorial(); + } + + public static gamma(value: DecimalSource, _other?: never): Decimal { + return D(value).gamma(); + } + + public static lngamma(value: DecimalSource, _other?: never): Decimal { + return D(value).lngamma(); + } + + public static exp(value: DecimalSource): Decimal { + return D(value).exp(); + } + + public static sqr(value: DecimalSource): Decimal { + return D(value).sqr(); + } + + public static sqrt(value: DecimalSource): Decimal { + return D(value).sqrt(); + } + + public static cube(value: DecimalSource): Decimal { + return D(value).cube(); + } + + public static cbrt(value: DecimalSource): Decimal { + return D(value).cbrt(); + } + + public static tetrate( + value: DecimalSource, + height = 2, + payload: DecimalSource = FC_NN(1, 0, 1) + ): Decimal { + return D(value).tetrate(height, payload); + } + + public static iteratedexp(value: DecimalSource, height = 2, payload = FC_NN(1, 0, 1)): Decimal { + return D(value).iteratedexp(height, payload); + } + + public static iteratedlog(value: DecimalSource, base: DecimalSource = 10, times = 1): Decimal { + return D(value).iteratedlog(base, times); + } + + public static layeradd10(value: DecimalSource, diff: DecimalSource): Decimal { + return D(value).layeradd10(diff); + } + + public static layeradd(value: DecimalSource, diff: number, base = 10): Decimal { + return D(value).layeradd(diff, base); + } + + public static slog(value: DecimalSource, base = 10): Decimal { + return D(value).slog(base); + } + + public static lambertw(value: DecimalSource): Decimal { + return D(value).lambertw(); + } + + public static ssqrt(value: DecimalSource): Decimal { + return D(value).ssqrt(); + } + + public static pentate( + value: DecimalSource, + height = 2, + payload: DecimalSource = FC_NN(1, 0, 1) + ): Decimal { + return D(value).pentate(height, payload); + } + + /** + * If you're willing to spend 'resourcesAvailable' and want to buy something + * with exponentially increasing cost each purchase (start at priceStart, + * multiply by priceRatio, already own currentOwned), how much of it can you buy? + * Adapted from Trimps source code. + */ + + public static affordGeometricSeries( + resourcesAvailable: DecimalSource, + priceStart: DecimalSource, + priceRatio: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.affordGeometricSeries_core( + D(resourcesAvailable), + D(priceStart), + D(priceRatio), + currentOwned + ); + } + /** + * How much resource would it cost to buy (numItems) items if you already have currentOwned, + * the initial price is priceStart and it multiplies by priceRatio each purchase? + */ + + public static sumGeometricSeries( + numItems: DecimalSource, + priceStart: DecimalSource, + priceRatio: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.sumGeometricSeries_core(numItems, D(priceStart), D(priceRatio), currentOwned); + } + /** + * If you're willing to spend 'resourcesAvailable' and want to buy something with additively + * increasing cost each purchase (start at priceStart, add by priceAdd, already own currentOwned), + * how much of it can you buy? + */ + + public static affordArithmeticSeries( + resourcesAvailable: DecimalSource, + priceStart: DecimalSource, + priceAdd: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.affordArithmeticSeries_core( + D(resourcesAvailable), + D(priceStart), + D(priceAdd), + D(currentOwned) + ); + } + /** + * How much resource would it cost to buy (numItems) items if you already have currentOwned, + * the initial price is priceStart and it adds priceAdd each purchase? + * Adapted from http://www.mathwords.com/a/arithmetic_series.htm + */ + + public static sumArithmeticSeries( + numItems: DecimalSource, + priceStart: DecimalSource, + priceAdd: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.sumArithmeticSeries_core( + D(numItems), + D(priceStart), + D(priceAdd), + D(currentOwned) + ); + } + /** + * When comparing two purchases that cost (resource) and increase your resource/sec by (deltaRpS), + * the lowest efficiency score is the better one to purchase. + * From Frozen Cookies: + * http://cookieclicker.wikia.com/wiki/Frozen_Cookies_(JavaScript_Add-on)#Efficiency.3F_What.27s_that.3F + */ + + public static efficiencyOfPurchase( + cost: DecimalSource, + currentRpS: DecimalSource, + deltaRpS: DecimalSource + ): Decimal { + return this.efficiencyOfPurchase_core(D(cost), D(currentRpS), D(deltaRpS)); + } + + public static randomDecimalForTesting(maxLayers: number): Decimal { + // NOTE: This doesn't follow any kind of sane random distribution, so use this for testing purposes only. + //5% of the time, return 0 + if (Math.random() * 20 < 1) { + return FC_NN(0, 0, 0); + } + + const randomsign = Math.random() > 0.5 ? 1 : -1; + + //5% of the time, return 1 or -1 + if (Math.random() * 20 < 1) { + return FC_NN(randomsign, 0, 1); + } + + //pick a random layer + const layer = Math.floor(Math.random() * (maxLayers + 1)); + + let randomexp = layer === 0 ? Math.random() * 616 - 308 : Math.random() * 16; + //10% of the time, make it a simple power of 10 + if (Math.random() > 0.9) { + randomexp = Math.trunc(randomexp); + } + let randommag = Math.pow(10, randomexp); + //10% of the time, trunc mag + if (Math.random() > 0.9) { + randommag = Math.trunc(randommag); + } + return FC(randomsign, layer, randommag); + } + + public static affordGeometricSeries_core( + resourcesAvailable: Decimal, + priceStart: Decimal, + priceRatio: Decimal, + currentOwned: DecimalSource + ): Decimal { + const actualStart = priceStart.mul(priceRatio.pow(currentOwned)); + return Decimal.floor( + resourcesAvailable + .div(actualStart) + .mul(priceRatio.sub(1)) + .add(1) + .log10() + .div(priceRatio.log10()) + ); + } + + public static sumGeometricSeries_core( + numItems: DecimalSource, + priceStart: Decimal, + priceRatio: Decimal, + currentOwned: DecimalSource + ): Decimal { + return priceStart + .mul(priceRatio.pow(currentOwned)) + .mul(Decimal.sub(1, priceRatio.pow(numItems))) + .div(Decimal.sub(1, priceRatio)); + } + + public static affordArithmeticSeries_core( + resourcesAvailable: Decimal, + priceStart: Decimal, + priceAdd: Decimal, + currentOwned: Decimal + ): Decimal { + // n = (-(a-d/2) + sqrt((a-d/2)^2+2dS))/d + // where a is actualStart, d is priceAdd and S is resourcesAvailable + // then floor it and you're done! + const actualStart = priceStart.add(currentOwned.mul(priceAdd)); + const b = actualStart.sub(priceAdd.div(2)); + const b2 = b.pow(2); + return b + .neg() + .add(b2.add(priceAdd.mul(resourcesAvailable).mul(2)).sqrt()) + .div(priceAdd) + .floor(); + } + + public static sumArithmeticSeries_core( + numItems: Decimal, + priceStart: Decimal, + priceAdd: Decimal, + currentOwned: Decimal + ): Decimal { + const actualStart = priceStart.add(currentOwned.mul(priceAdd)); // (n/2)*(2*a+(n-1)*d) + + return numItems.div(2).mul(actualStart.mul(2).plus(numItems.sub(1).mul(priceAdd))); + } + + public static efficiencyOfPurchase_core( + cost: Decimal, + currentRpS: Decimal, + deltaRpS: Decimal + ): Decimal { + return cost.div(currentRpS).add(cost.div(deltaRpS)); + } + + public normalize(): this { + /* + PSEUDOCODE: + Whenever we are partially 0 (sign is 0 or mag and layer is 0), make it fully 0. + Whenever we are at or hit layer 0, extract sign from negative mag. + If layer === 0 and mag < FIRST_NEG_LAYER (1/9e15), shift to 'first negative layer' (add layer, log10 mag). + While abs(mag) > EXP_LIMIT (9e15), layer += 1, mag = maglog10(mag). + While abs(mag) < LAYER_DOWN (15.954) and layer > 0, layer -= 1, mag = pow(10, mag). + + When we're done, all of the following should be true OR one of the numbers is not IsFinite OR layer is not IsInteger (error state): + Any 0 is totally zero (0, 0, 0). + Anything layer 0 has mag 0 OR mag > 1/9e15 and < 9e15. + Anything layer 1 or higher has abs(mag) >= 15.954 and < 9e15. + We will assume in calculations that all Decimals are either erroneous or satisfy these criteria. (Otherwise: Garbage in, garbage out.) + */ + if (this.sign === 0 || (this.mag === 0 && this.layer === 0)) { + this.sign = 0; + this.mag = 0; + this.layer = 0; + return this; + } + + if (this.layer === 0 && this.mag < 0) { + //extract sign from negative mag at layer 0 + this.mag = -this.mag; + this.sign = -this.sign; + } + + //Handle shifting from layer 0 to negative layers. + if (this.layer === 0 && this.mag < FIRST_NEG_LAYER) { + this.layer += 1; + this.mag = Math.log10(this.mag); + return this; + } + + let absmag = Math.abs(this.mag); + let signmag = Math.sign(this.mag); + + if (absmag >= EXP_LIMIT) { + this.layer += 1; + this.mag = signmag * Math.log10(absmag); + return this; + } else { + while (absmag < LAYER_DOWN && this.layer > 0) { + this.layer -= 1; + if (this.layer === 0) { + this.mag = Math.pow(10, this.mag); + } else { + this.mag = signmag * Math.pow(10, absmag); + absmag = Math.abs(this.mag); + signmag = Math.sign(this.mag); + } + } + if (this.layer === 0) { + if (this.mag < 0) { + //extract sign from negative mag at layer 0 + this.mag = -this.mag; + this.sign = -this.sign; + } else if (this.mag === 0) { + //excessive rounding can give us all zeroes + this.sign = 0; + } + } + } + + return this; + } + + public fromComponents(sign: number, layer: number, mag: number): this { + this.sign = sign; + this.layer = layer; + this.mag = mag; + + this.normalize(); + return this; + } + + public fromComponents_noNormalize(sign: number, layer: number, mag: number): this { + this.sign = sign; + this.layer = layer; + this.mag = mag; + return this; + } + + public fromMantissaExponent(mantissa: number, exponent: number): this { + this.layer = 1; + this.sign = Math.sign(mantissa); + mantissa = Math.abs(mantissa); + this.mag = exponent + Math.log10(mantissa); + + this.normalize(); + return this; + } + + public fromMantissaExponent_noNormalize(mantissa: number, exponent: number): this { + //The idea of 'normalizing' a break_infinity.js style Decimal doesn't really apply. So just do the same thing. + this.fromMantissaExponent(mantissa, exponent); + return this; + } + + public fromDecimal(value: Decimal): this { + this.sign = value.sign; + this.layer = value.layer; + this.mag = value.mag; + return this; + } + + public fromNumber(value: number): this { + this.mag = Math.abs(value); + this.sign = Math.sign(value); + this.layer = 0; + this.normalize(); + return this; + } + + public fromString(value: string): Decimal { + if (IGNORE_COMMAS) { + value = value.replace(",", ""); + } else if (COMMAS_ARE_DECIMAL_POINTS) { + value = value.replace(",", "."); + } + + //Handle x^^^y format. + const pentationparts = value.split("^^^"); + if (pentationparts.length === 2) { + const base = parseFloat(pentationparts[0]); + const height = parseFloat(pentationparts[1]); + const heightparts = pentationparts[1].split(";"); + let payload = 1; + if (heightparts.length === 2) { + payload = parseFloat(heightparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.pentate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle x^^y format. + const tetrationparts = value.split("^^"); + if (tetrationparts.length === 2) { + const base = parseFloat(tetrationparts[0]); + const height = parseFloat(tetrationparts[1]); + const heightparts = tetrationparts[1].split(";"); + let payload = 1; + if (heightparts.length === 2) { + payload = parseFloat(heightparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle x^y format. + const powparts = value.split("^"); + if (powparts.length === 2) { + const base = parseFloat(powparts[0]); + const exponent = parseFloat(powparts[1]); + if (isFinite(base) && isFinite(exponent)) { + const result = Decimal.pow(base, exponent); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle various cases involving it being a Big Number. + value = value.trim().toLowerCase(); + + //handle X PT Y format. + let base; + let height; + let ptparts = value.split("pt"); + if (ptparts.length === 2) { + base = 10; + height = parseFloat(ptparts[0]); + ptparts[1] = ptparts[1].replace("(", ""); + ptparts[1] = ptparts[1].replace(")", ""); + let payload = parseFloat(ptparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //handle XpY format (it's the same thing just with p). + ptparts = value.split("p"); + if (ptparts.length === 2) { + base = 10; + height = parseFloat(ptparts[0]); + ptparts[1] = ptparts[1].replace("(", ""); + ptparts[1] = ptparts[1].replace(")", ""); + let payload = parseFloat(ptparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + const parts = value.split("e"); + const ecount = parts.length - 1; + + //Handle numbers that are exactly floats (0 or 1 es). + if (ecount === 0) { + const numberAttempt = parseFloat(value); + if (isFinite(numberAttempt)) { + return this.fromNumber(numberAttempt); + } + } else if (ecount === 1) { + //Very small numbers ("2e-3000" and so on) may look like valid floats but round to 0. + const numberAttempt = parseFloat(value); + if (isFinite(numberAttempt) && numberAttempt !== 0) { + return this.fromNumber(numberAttempt); + } + } + + //Handle new (e^N)X format. + const newparts = value.split("e^"); + if (newparts.length === 2) { + this.sign = 1; + if (newparts[0].charAt(0) == "-") { + this.sign = -1; + } + let layerstring = ""; + for (let i = 0; i < newparts[1].length; ++i) { + const chrcode = newparts[1].charCodeAt(i); + if ((chrcode >= 43 && chrcode <= 57) || chrcode === 101) { + //is "0" to "9" or "+" or "-" or "." or "e" (or "," or "/") + layerstring += newparts[1].charAt(i); + } //we found the end of the layer count + else { + this.layer = parseFloat(layerstring); + this.mag = parseFloat(newparts[1].substr(i + 1)); + this.normalize(); + return this; + } + } + } + + if (ecount < 1) { + this.sign = 0; + this.layer = 0; + this.mag = 0; + return this; + } + const mantissa = parseFloat(parts[0]); + if (mantissa === 0) { + this.sign = 0; + this.layer = 0; + this.mag = 0; + return this; + } + let exponent = parseFloat(parts[parts.length - 1]); + //handle numbers like AeBeC and AeeeeBeC + if (ecount >= 2) { + const me = parseFloat(parts[parts.length - 2]); + if (isFinite(me)) { + exponent *= Math.sign(me); + exponent += f_maglog10(me); + } + } + + //Handle numbers written like eee... (N es) X + if (!isFinite(mantissa)) { + this.sign = parts[0] === "-" ? -1 : 1; + this.layer = ecount; + this.mag = exponent; + } + //Handle numbers written like XeY + else if (ecount === 1) { + this.sign = Math.sign(mantissa); + this.layer = 1; + //Example: 2e10 is equal to 10^log10(2e10) which is equal to 10^(10+log10(2)) + this.mag = exponent + Math.log10(Math.abs(mantissa)); + } + //Handle numbers written like Xeee... (N es) Y + else { + this.sign = Math.sign(mantissa); + this.layer = ecount; + if (ecount === 2) { + const result = Decimal.mul(FC(1, 2, exponent), D(mantissa)); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } else { + //at eee and above, mantissa is too small to be recognizable! + this.mag = exponent; + } + } + + this.normalize(); + return this; + } + + public fromValue(value: DecimalSource): Decimal { + if (value instanceof Decimal || (value != null && typeof value === "object" && "sign" in value && "mag" in value && "layer" in value)) { + return this.fromDecimal(value); + } + + if (typeof value === "number") { + return this.fromNumber(value); + } + + if (typeof value === "string") { + return this.fromString(value); + } + + this.sign = 0; + this.layer = 0; + this.mag = 0; + return this; + } + + public toNumber(): number { + if (!Number.isFinite(this.layer)) { + return Number.NaN; + } + if (this.layer === 0) { + return this.sign * this.mag; + } else if (this.layer === 1) { + return this.sign * Math.pow(10, this.mag); + } //overflow for any normalized Decimal + else { + return this.mag > 0 + ? this.sign > 0 + ? Number.POSITIVE_INFINITY + : Number.NEGATIVE_INFINITY + : 0; + } + } + + public mantissaWithDecimalPlaces(places: number): number { + // https://stackoverflow.com/a/37425022 + if (isNaN(this.m)) { + return Number.NaN; + } + + if (this.m === 0) { + return 0; + } + + return decimalPlaces(this.m, places); + } + + public magnitudeWithDecimalPlaces(places: number): number { + // https://stackoverflow.com/a/37425022 + if (isNaN(this.mag)) { + return Number.NaN; + } + + if (this.mag === 0) { + return 0; + } + + return decimalPlaces(this.mag, places); + } + + public toString(): string { + if (isNaN(this.layer) || isNaN(this.sign) || isNaN(this.mag)) { + return "NaN"; + } + if (this.mag === Number.POSITIVE_INFINITY || this.layer === Number.POSITIVE_INFINITY) { + return this.sign === 1 ? "Infinity" : "-Infinity"; + } + + if (this.layer === 0) { + if ((this.mag < 1e21 && this.mag > 1e-7) || this.mag === 0) { + return (this.sign * this.mag).toString(); + } + return this.m + "e" + this.e; + } else if (this.layer === 1) { + return this.m + "e" + this.e; + } else { + //layer 2+ + if (this.layer <= MAX_ES_IN_A_ROW) { + return (this.sign === -1 ? "-" : "") + "e".repeat(this.layer) + this.mag; + } else { + return (this.sign === -1 ? "-" : "") + "(e^" + this.layer + ")" + this.mag; + } + } + } + + public toExponential(places: number): string { + if (this.layer === 0) { + return (this.sign * this.mag).toExponential(places); + } + return this.toStringWithDecimalPlaces(places); + } + + public toFixed(places: number): string { + if (this.layer === 0) { + return (this.sign * this.mag).toFixed(places); + } + return this.toStringWithDecimalPlaces(places); + } + + public toPrecision(places: number): string { + if (this.e <= -7) { + return this.toExponential(places - 1); + } + + if (places > this.e) { + return this.toFixed(places - this.exponent - 1); + } + + return this.toExponential(places - 1); + } + + public valueOf(): string { + return this.toString(); + } + + public toJSON(): string { + return this.toString(); + } + + public toStringWithDecimalPlaces(places: number): string { + if (this.layer === 0) { + if ((this.mag < 1e21 && this.mag > 1e-7) || this.mag === 0) { + return (this.sign * this.mag).toFixed(places); + } + return decimalPlaces(this.m, places) + "e" + decimalPlaces(this.e, places); + } else if (this.layer === 1) { + return decimalPlaces(this.m, places) + "e" + decimalPlaces(this.e, places); + } else { + //layer 2+ + if (this.layer <= MAX_ES_IN_A_ROW) { + return ( + (this.sign === -1 ? "-" : "") + + "e".repeat(this.layer) + + decimalPlaces(this.mag, places) + ); + } else { + return ( + (this.sign === -1 ? "-" : "") + + "(e^" + + this.layer + + ")" + + decimalPlaces(this.mag, places) + ); + } + } + } + + public abs(): Decimal { + return FC_NN(this.sign === 0 ? 0 : 1, this.layer, this.mag); + } + + public neg(): Decimal { + return FC_NN(-this.sign, this.layer, this.mag); + } + + public negate(): Decimal { + return this.neg(); + } + + public negated(): Decimal { + return this.neg(); + } + + // public sign () { + // return this.sign; + // } + + public sgn(): number { + return this.sign; + } + + public round(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.round(this.mag)); + } + return this; + } + + public floor(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.floor(this.mag)); + } + return this; + } + + public ceil(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.ceil(this.mag)); + } + return this; + } + + public trunc(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.trunc(this.mag)); + } + return this; + } + + public add(value: DecimalSource): this | Decimal { + const decimal = D(value); + + //inf/nan check + if (!Number.isFinite(this.layer)) { + return this; + } + if (!Number.isFinite(decimal.layer)) { + return decimal; + } + + //Special case - if one of the numbers is 0, return the other number. + if (this.sign === 0) { + return decimal; + } + if (decimal.sign === 0) { + return this; + } + + //Special case - Adding a number to its negation produces 0, no matter how large. + if ( + this.sign === -decimal.sign && + this.layer === decimal.layer && + this.mag === decimal.mag + ) { + return FC_NN(0, 0, 0); + } + + let a; + let b; + + //Special case: If one of the numbers is layer 2 or higher, just take the bigger number. + if (this.layer >= 2 || decimal.layer >= 2) { + return this.maxabs(decimal); + } + + if (Decimal.cmpabs(this, decimal) > 0) { + a = this; + b = decimal; + } else { + a = decimal; + b = this; + } + + if (a.layer === 0 && b.layer === 0) { + return D(a.sign * a.mag + b.sign * b.mag); + } + + const layera = a.layer * Math.sign(a.mag); + const layerb = b.layer * Math.sign(b.mag); + + //If one of the numbers is 2+ layers higher than the other, just take the bigger number. + if (layera - layerb >= 2) { + return a; + } + + if (layera === 0 && layerb === -1) { + if (Math.abs(b.mag - Math.log10(a.mag)) > MAX_SIGNIFICANT_DIGITS) { + return a; + } else { + const magdiff = Math.pow(10, Math.log10(a.mag) - b.mag); + const mantissa = b.sign + a.sign * magdiff; + return FC(Math.sign(mantissa), 1, b.mag + Math.log10(Math.abs(mantissa))); + } + } + + if (layera === 1 && layerb === 0) { + if (Math.abs(a.mag - Math.log10(b.mag)) > MAX_SIGNIFICANT_DIGITS) { + return a; + } else { + const magdiff = Math.pow(10, a.mag - Math.log10(b.mag)); + const mantissa = b.sign + a.sign * magdiff; + return FC( + Math.sign(mantissa), + 1, + Math.log10(b.mag) + Math.log10(Math.abs(mantissa)) + ); + } + } + + if (Math.abs(a.mag - b.mag) > MAX_SIGNIFICANT_DIGITS) { + return a; + } else { + const magdiff = Math.pow(10, a.mag - b.mag); + const mantissa = b.sign + a.sign * magdiff; + return FC(Math.sign(mantissa), 1, b.mag + Math.log10(Math.abs(mantissa))); + } + + throw Error("Bad arguments to add: " + this + ", " + value); + } + + public plus(value: DecimalSource): Decimal { + return this.add(value); + } + + public sub(value: DecimalSource): Decimal { + return this.add(D(value).neg()); + } + + public subtract(value: DecimalSource): Decimal { + return this.sub(value); + } + + public minus(value: DecimalSource): Decimal { + return this.sub(value); + } + + public mul(value: DecimalSource): Decimal { + const decimal = D(value); + + //inf/nan check + if (!Number.isFinite(this.layer)) { + return this; + } + if (!Number.isFinite(decimal.layer)) { + return decimal; + } + + //Special case - if one of the numbers is 0, return 0. + if (this.sign === 0 || decimal.sign === 0) { + return FC_NN(0, 0, 0); + } + + //Special case - Multiplying a number by its own reciprocal yields +/- 1, no matter how large. + if (this.layer === decimal.layer && this.mag === -decimal.mag) { + return FC_NN(this.sign * decimal.sign, 0, 1); + } + + let a; + let b; + + //Which number is bigger in terms of its multiplicative distance from 1? + if ( + this.layer > decimal.layer || + (this.layer == decimal.layer && Math.abs(this.mag) > Math.abs(decimal.mag)) + ) { + a = this; + b = decimal; + } else { + a = decimal; + b = this; + } + + if (a.layer === 0 && b.layer === 0) { + return D(a.sign * b.sign * a.mag * b.mag); + } + + //Special case: If one of the numbers is layer 3 or higher or one of the numbers is 2+ layers bigger than the other, just take the bigger number. + if (a.layer >= 3 || a.layer - b.layer >= 2) { + return FC(a.sign * b.sign, a.layer, a.mag); + } + + if (a.layer === 1 && b.layer === 0) { + return FC(a.sign * b.sign, 1, a.mag + Math.log10(b.mag)); + } + + if (a.layer === 1 && b.layer === 1) { + return FC(a.sign * b.sign, 1, a.mag + b.mag); + } + + if (a.layer === 2 && b.layer === 1) { + const newmag = FC(Math.sign(a.mag), a.layer - 1, Math.abs(a.mag)).add( + FC(Math.sign(b.mag), b.layer - 1, Math.abs(b.mag)) + ); + return FC(a.sign * b.sign, newmag.layer + 1, newmag.sign * newmag.mag); + } + + if (a.layer === 2 && b.layer === 2) { + const newmag = FC(Math.sign(a.mag), a.layer - 1, Math.abs(a.mag)).add( + FC(Math.sign(b.mag), b.layer - 1, Math.abs(b.mag)) + ); + return FC(a.sign * b.sign, newmag.layer + 1, newmag.sign * newmag.mag); + } + + throw Error("Bad arguments to mul: " + this + ", " + value); + } + + public multiply(value: DecimalSource): Decimal { + return this.mul(value); + } + + public times(value: DecimalSource): Decimal { + return this.mul(value); + } + + public div(value: DecimalSource): Decimal { + const decimal = D(value); + return this.mul(decimal.recip()); + } + + public divide(value: DecimalSource): Decimal { + return this.div(value); + } + + public divideBy(value: DecimalSource): Decimal { + return this.div(value); + } + + public dividedBy(value: DecimalSource): Decimal { + return this.div(value); + } + + public recip(): Decimal { + if (this.mag === 0) { + return Decimal.dNaN; + } else if (this.layer === 0) { + return FC(this.sign, 0, 1 / this.mag); + } else { + return FC(this.sign, this.layer, -this.mag); + } + } + + public reciprocal(): Decimal { + return this.recip(); + } + + public reciprocate(): Decimal { + return this.recip(); + } + + /** + * -1 for less than value, 0 for equals value, 1 for greater than value + */ + public cmp(value: DecimalSource): CompareResult { + const decimal = D(value); + if (this.sign > decimal.sign) { + return 1; + } + if (this.sign < decimal.sign) { + return -1; + } + return (this.sign * this.cmpabs(value)) as CompareResult; + } + + public cmpabs(value: DecimalSource): CompareResult { + const decimal = D(value); + const layera = this.mag > 0 ? this.layer : -this.layer; + const layerb = decimal.mag > 0 ? decimal.layer : -decimal.layer; + if (layera > layerb) { + return 1; + } + if (layera < layerb) { + return -1; + } + if (this.mag > decimal.mag) { + return 1; + } + if (this.mag < decimal.mag) { + return -1; + } + return 0; + } + + public compare(value: DecimalSource): CompareResult { + return this.cmp(value); + } + + public isNan(): boolean { + return isNaN(this.sign) || isNaN(this.layer) || isNaN(this.mag); + } + + public isFinite(): boolean { + return isFinite(this.sign) && isFinite(this.layer) && isFinite(this.mag); + } + + public eq(value: DecimalSource): boolean { + const decimal = D(value); + return ( + this.sign === decimal.sign && this.layer === decimal.layer && this.mag === decimal.mag + ); + } + + public equals(value: DecimalSource): boolean { + return this.eq(value); + } + + public neq(value: DecimalSource): boolean { + return !this.eq(value); + } + + public notEquals(value: DecimalSource): boolean { + return this.neq(value); + } + + public lt(value: DecimalSource): boolean { + return this.cmp(value) === -1; + } + + public lte(value: DecimalSource): boolean { + return !this.gt(value); + } + + public gt(value: DecimalSource): boolean { + return this.cmp(value) === 1; + } + + public gte(value: DecimalSource): boolean { + return !this.lt(value); + } + + public max(value: DecimalSource): Decimal { + const decimal = D(value); + return this.lt(decimal) ? decimal : this; + } + + public min(value: DecimalSource): Decimal { + const decimal = D(value); + return this.gt(decimal) ? decimal : this; + } + + public maxabs(value: DecimalSource): Decimal { + const decimal = D(value); + return this.cmpabs(decimal) < 0 ? decimal : this; + } + + public minabs(value: DecimalSource): Decimal { + const decimal = D(value); + return this.cmpabs(decimal) > 0 ? decimal : this; + } + + public clamp(min: DecimalSource, max: DecimalSource): Decimal { + return this.max(min).min(max); + } + + public clampMin(min: DecimalSource): Decimal { + return this.max(min); + } + + public clampMax(max: DecimalSource): Decimal { + return this.min(max); + } + + public cmp_tolerance(value: DecimalSource, tolerance: number): CompareResult { + const decimal = D(value); + return this.eq_tolerance(decimal, tolerance) ? 0 : this.cmp(decimal); + } + + public compare_tolerance(value: DecimalSource, tolerance: number): CompareResult { + return this.cmp_tolerance(value, tolerance); + } + + /** + * Tolerance is a relative tolerance, multiplied by the greater of the magnitudes of the two arguments. + * For example, if you put in 1e-9, then any number closer to the + * larger number than (larger number)*1e-9 will be considered equal. + */ + public eq_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); // https://stackoverflow.com/a/33024979 + if (tolerance == null) { + tolerance = 1e-7; + } + //Numbers that are too far away are never close. + if (this.sign !== decimal.sign) { + return false; + } + if (Math.abs(this.layer - decimal.layer) > 1) { + return false; + } + // return abs(a-b) <= tolerance * max(abs(a), abs(b)) + let magA = this.mag; + let magB = decimal.mag; + if (this.layer > decimal.layer) { + magB = f_maglog10(magB); + } + if (this.layer < decimal.layer) { + magA = f_maglog10(magA); + } + return Math.abs(magA - magB) <= tolerance * Math.max(Math.abs(magA), Math.abs(magB)); + } + + public equals_tolerance(value: DecimalSource, tolerance: number): boolean { + return this.eq_tolerance(value, tolerance); + } + + public neq_tolerance(value: DecimalSource, tolerance: number): boolean { + return !this.eq_tolerance(value, tolerance); + } + + public notEquals_tolerance(value: DecimalSource, tolerance: number): boolean { + return this.neq_tolerance(value, tolerance); + } + + public lt_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return !this.eq_tolerance(decimal, tolerance) && this.lt(decimal); + } + + public lte_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return this.eq_tolerance(decimal, tolerance) || this.lt(decimal); + } + + public gt_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return !this.eq_tolerance(decimal, tolerance) && this.gt(decimal); + } + + public gte_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return this.eq_tolerance(decimal, tolerance) || this.gt(decimal); + } + + public pLog10(): Decimal { + if (this.lt(Decimal.dZero)) { + return Decimal.dZero; + } + return this.log10(); + } + + public absLog10(): Decimal { + if (this.sign === 0) { + return Decimal.dNaN; + } else if (this.layer > 0) { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } else { + return FC(1, 0, Math.log10(this.mag)); + } + } + + public log10(): Decimal { + if (this.sign <= 0) { + return Decimal.dNaN; + } else if (this.layer > 0) { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } else { + return FC(this.sign, 0, Math.log10(this.mag)); + } + } + + public log(base: DecimalSource): Decimal { + base = D(base); + if (this.sign <= 0) { + return Decimal.dNaN; + } + if (base.sign <= 0) { + return Decimal.dNaN; + } + if (base.sign === 1 && base.layer === 0 && base.mag === 1) { + return Decimal.dNaN; + } else if (this.layer === 0 && base.layer === 0) { + return FC(this.sign, 0, Math.log(this.mag) / Math.log(base.mag)); + } + + return Decimal.div(this.log10(), base.log10()); + } + + public log2(): Decimal { + if (this.sign <= 0) { + return Decimal.dNaN; + } else if (this.layer === 0) { + return FC(this.sign, 0, Math.log2(this.mag)); + } else if (this.layer === 1) { + return FC(Math.sign(this.mag), 0, Math.abs(this.mag) * 3.321928094887362); //log2(10) + } else if (this.layer === 2) { + return FC(Math.sign(this.mag), 1, Math.abs(this.mag) + 0.5213902276543247); //-log10(log10(2)) + } else { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } + } + + public ln(): Decimal { + if (this.sign <= 0) { + return Decimal.dNaN; + } else if (this.layer === 0) { + return FC(this.sign, 0, Math.log(this.mag)); + } else if (this.layer === 1) { + return FC(Math.sign(this.mag), 0, Math.abs(this.mag) * 2.302585092994046); //ln(10) + } else if (this.layer === 2) { + return FC(Math.sign(this.mag), 1, Math.abs(this.mag) + 0.36221568869946325); //log10(log10(e)) + } else { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } + } + + public logarithm(base: DecimalSource): Decimal { + return this.log(base); + } + + public pow(value: DecimalSource): Decimal { + const decimal = D(value); + const a = this; + const b = decimal; + + //special case: if a is 0, then return 0 (UNLESS b is 0, then return 1) + if (a.sign === 0) { + return b.eq(0) ? FC_NN(1, 0, 1) : a; + } + //special case: if a is 1, then return 1 + if (a.sign === 1 && a.layer === 0 && a.mag === 1) { + return a; + } + //special case: if b is 0, then return 1 + if (b.sign === 0) { + return FC_NN(1, 0, 1); + } + //special case: if b is 1, then return a + if (b.sign === 1 && b.layer === 0 && b.mag === 1) { + return a; + } + + const result = a + .absLog10() + .mul(b) + .pow10(); + + if (this.sign === -1) { + if (Math.abs(b.toNumber() % 2) % 2 === 1) { + return result.neg(); + } else if (Math.abs(b.toNumber() % 2) % 2 === 0) { + return result; + } + return Decimal.dNaN; + } + + return result; + } + + public pow10(): Decimal { + /* + There are four cases we need to consider: + 1) positive sign, positive mag (e15, ee15): +1 layer (e.g. 10^15 becomes e15, 10^e15 becomes ee15) + 2) negative sign, positive mag (-e15, -ee15): +1 layer but sign and mag sign are flipped (e.g. 10^-15 becomes e-15, 10^-e15 becomes ee-15) + 3) positive sign, negative mag (e-15, ee-15): layer 0 case would have been handled in the Math.pow check, so just return 1 + 4) negative sign, negative mag (-e-15, -ee-15): layer 0 case would have been handled in the Math.pow check, so just return 1 + */ + + if (!Number.isFinite(this.layer) || !Number.isFinite(this.mag)) { + return Decimal.dNaN; + } + + let a = this; + + //handle layer 0 case - if no precision is lost just use Math.pow, else promote one layer + if (a.layer === 0) { + const newmag = Math.pow(10, a.sign * a.mag); + if (Number.isFinite(newmag) && Math.abs(newmag) >= 0.1) { + return FC(1, 0, newmag); + } else { + if (a.sign === 0) { + return Decimal.dOne; + } else { + a = FC_NN(a.sign, a.layer + 1, Math.log10(a.mag)) as this; + } + } + } + + //handle all 4 layer 1+ cases individually + if (a.sign > 0 && a.mag >= 0) { + return FC(a.sign, a.layer + 1, a.mag); + } + if (a.sign < 0 && a.mag >= 0) { + return FC(-a.sign, a.layer + 1, -a.mag); + } + //both the negative mag cases are identical: one +/- rounding error + return Decimal.dOne; + } + + public pow_base(value: DecimalSource): Decimal { + return D(value).pow(this); + } + + public root(value: DecimalSource): Decimal { + const decimal = D(value); + return this.pow(decimal.recip()); + } + + public factorial(): Decimal { + if (this.mag < 0) { + return this.add(1).gamma(); + } else if (this.layer === 0) { + return this.add(1).gamma(); + } else if (this.layer === 1) { + return Decimal.exp(Decimal.mul(this, Decimal.ln(this).sub(1))); + } else { + return Decimal.exp(this); + } + } + + //from HyperCalc source code + public gamma(): Decimal { + if (this.mag < 0) { + return this.recip(); + } else if (this.layer === 0) { + if (this.lt(FC_NN(1, 0, 24))) { + return D(f_gamma(this.sign * this.mag)); + } + + const t = this.mag - 1; + let l = 0.9189385332046727; //0.5*Math.log(2*Math.PI) + l = l + (t + 0.5) * Math.log(t); + l = l - t; + const n2 = t * t; + let np = t; + let lm = 12 * np; + let adj = 1 / lm; + let l2 = l + adj; + if (l2 === l) { + return Decimal.exp(l); + } + + l = l2; + np = np * n2; + lm = 360 * np; + adj = 1 / lm; + l2 = l - adj; + if (l2 === l) { + return Decimal.exp(l); + } + + l = l2; + np = np * n2; + lm = 1260 * np; + let lt = 1 / lm; + l = l + lt; + np = np * n2; + lm = 1680 * np; + lt = 1 / lm; + l = l - lt; + return Decimal.exp(l); + } else if (this.layer === 1) { + return Decimal.exp(Decimal.mul(this, Decimal.ln(this).sub(1))); + } else { + return Decimal.exp(this); + } + } + + public lngamma(): Decimal { + return this.gamma().ln(); + } + + public exp(): Decimal { + if (this.mag < 0) { + return Decimal.dOne; + } + if (this.layer === 0 && this.mag <= 709.7) { + return D(Math.exp(this.sign * this.mag)); + } else if (this.layer === 0) { + return FC(1, 1, this.sign * Math.log10(Math.E) * this.mag); + } else if (this.layer === 1) { + return FC(1, 2, this.sign * (Math.log10(0.4342944819032518) + this.mag)); + } else { + return FC(1, this.layer + 1, this.sign * this.mag); + } + } + + public sqr(): Decimal { + return this.pow(2); + } + + public sqrt(): Decimal { + if (this.layer === 0) { + return D(Math.sqrt(this.sign * this.mag)); + } else if (this.layer === 1) { + return FC(1, 2, Math.log10(this.mag) - 0.3010299956639812); + } else { + const result = Decimal.div(FC_NN(this.sign, this.layer - 1, this.mag), FC_NN(1, 0, 2)); + result.layer += 1; + result.normalize(); + return result; + } + } + + public cube(): Decimal { + return this.pow(3); + } + + public cbrt(): Decimal { + return this.pow(1 / 3); + } + + //Tetration/tetrate: The result of exponentiating 'this' to 'this' 'height' times in a row. https://en.wikipedia.org/wiki/Tetration + //If payload != 1, then this is 'iterated exponentiation', the result of exping (payload) to base (this) (height) times. https://andydude.github.io/tetration/archives/tetration2/ident.html + //Works with negative and positive real heights. + public tetrate(height = 2, payload: DecimalSource = FC_NN(1, 0, 1)): Decimal { + //x^^1 == x + if (height === 1) { + return Decimal.pow(this, payload); + } + //x^^0 == 1 + if (height === 0) { + return new Decimal(payload); + } + //1^^x == 1 + if (this.eq(Decimal.dOne)) { + return Decimal.dOne; + } + //-1^^x == -1 + if (this.eq(-1)) { + return Decimal.pow(this, payload); + } + + if (height === Number.POSITIVE_INFINITY) { + const this_num = this.toNumber(); + //within the convergence range? + if (this_num <= 1.44466786100976613366 && this_num >= 0.06598803584531253708) { + //hotfix for the very edge of the number range not being handled properly + if (this_num > 1.444667861009099) { + return new Decimal(Math.E); + } + //Formula for infinite height power tower. + const negln = Decimal.ln(this).neg(); + return negln.lambertw().div(negln); + } else if (this_num > 1.44466786100976613366) { + //explodes to infinity + return new Decimal(Number.POSITIVE_INFINITY); + } else { + //0.06598803584531253708 > this_num >= 0: never converges + //this_num < 0: quickly becomes a complex number + return Decimal.dNaN; + } + } + + //0^^x oscillates if we define 0^0 == 1 (which in javascript land we do), since then 0^^1 is 0, 0^^2 is 1, 0^^3 is 0, etc. payload is ignored + //using the linear approximation for height (TODO: don't know a better way to calculate it ATM, but it wouldn't surprise me if it's just NaN) + if (this.eq(Decimal.dZero)) { + let result = Math.abs((height + 1) % 2); + if (result > 1) { + result = 2 - result; + } + return new Decimal(result); + } + + if (height < 0) { + return Decimal.iteratedlog(payload, this, -height); + } + + payload = D(payload); + const oldheight = height; + height = Math.trunc(height); + const fracheight = oldheight - height; + + if (this.gt(Decimal.dZero) && this.lte(1.44466786100976613366)) { + //similar to 0^^n, flip-flops between two values, converging slowly (or if it's below 0.06598803584531253708, never. so once again, the fractional part at the end will be a linear approximation (TODO: again pending knowledge of how to approximate better, although tbh I think it should in reality just be NaN) + height = Math.min(10000, height); + for (let i = 0; i < height; ++i) { + const old_payload: Decimal = payload; + payload = this.pow(payload); + //stop early if we converge + if (old_payload.eq(payload)) { + return payload; + } + } + if (fracheight != 0) { + const next_payload = this.pow(payload); + return payload.mul(1 - fracheight).add(next_payload.mul(fracheight)); + } + return payload; + } + //TODO: base < 0, but it's hard for me to reason about (probably all non-integer heights are NaN automatically?) + + if (fracheight !== 0) { + if (payload.eq(Decimal.dOne)) { + //TODO: for bases above 10, revert to old linear approximation until I can think of something better + if (this.gt(10)) { + payload = this.pow(fracheight); + } else { + payload = D(Decimal.tetrate_critical(this.toNumber(), fracheight)); + //TODO: until the critical section grid can handle numbers below 2, scale them to the base + //TODO: maybe once the critical section grid has very large bases, this math can be appropriate for them too? I'll think about it + if (this.lt(2)) { + payload = payload + .sub(1) + .mul(this.minus(1)) + .plus(1); + } + } + } else { + if (this.eq(10)) { + payload = payload.layeradd10(fracheight); + } else { + payload = payload.layeradd(fracheight, this); + } + } + } + + for (let i = 0; i < height; ++i) { + payload = this.pow(payload); + //bail if we're NaN + if (!isFinite(payload.layer) || !isFinite(payload.mag)) { + return payload.normalize(); + } + //shortcut + if (payload.layer - this.layer > 3) { + return FC_NN(payload.sign, payload.layer + (height - i - 1), payload.mag); + } + //give up after 10000 iterations if nothing is happening + if (i > 10000) { + return payload; + } + } + return payload; + } + + //iteratedexp/iterated exponentiation: - all cases handled in tetrate, so just call it + public iteratedexp(height = 2, payload = FC_NN(1, 0, 1)): Decimal { + return this.tetrate(height, payload); + } + + //iterated log/repeated log: The result of applying log(base) 'times' times in a row. Approximately equal to subtracting (times) from the number's slog representation. Equivalent to tetrating to a negative height. + //Works with negative and positive real heights. + public iteratedlog(base: DecimalSource = 10, times = 1): Decimal { + if (times < 0) { + return Decimal.tetrate(base, -times, this); + } + + base = D(base); + let result = D(this); + const fulltimes = times; + times = Math.trunc(times); + const fraction = fulltimes - times; + if (result.layer - base.layer > 3) { + const layerloss = Math.min(times, result.layer - base.layer - 3); + times -= layerloss; + result.layer -= layerloss; + } + + for (let i = 0; i < times; ++i) { + result = result.log(base); + //bail if we're NaN + if (!isFinite(result.layer) || !isFinite(result.mag)) { + return result.normalize(); + } + //give up after 10000 iterations if nothing is happening + if (i > 10000) { + return result; + } + } + + //handle fractional part + if (fraction > 0 && fraction < 1) { + if (base.eq(10)) { + result = result.layeradd10(-fraction); + } else { + result = result.layeradd(-fraction, base); + } + } + + return result; + } + + //Super-logarithm, one of tetration's inverses, tells you what size power tower you'd have to tetrate base to to get number. By definition, will never be higher than 1.8e308 in break_eternity.js, since a power tower 1.8e308 numbers tall is the largest representable number. + // https://en.wikipedia.org/wiki/Super-logarithm + public slog(base: DecimalSource = 10): Decimal { + base = D(base); + + //special cases: + //slog base 0 or lower is NaN + if (base.lte(Decimal.dZero)) { + return Decimal.dNaN; + } + //slog base 1 is NaN + if (base.eq(Decimal.dOne)) { + return Decimal.dNaN; + } + //need to handle these small, wobbling bases specially + if (base.lt(Decimal.dOne)) { + if (this.eq(Decimal.dOne)) { + return Decimal.dZero; + } + if (this.eq(Decimal.dZero)) { + return Decimal.dNegOne; + } + //0 < this < 1: ambiguous (happens multiple times) + //this < 0: impossible (as far as I can tell) + //this > 1: partially complex (http://myweb.astate.edu/wpaulsen/tetcalc/tetcalc.html base 0.25 for proof) + return Decimal.dNaN; + } + //slog_n(0) is -1 + if (this.mag < 0 || this.eq(Decimal.dZero)) { + return Decimal.dNegOne; + } + + let result = 0; + let copy = D(this); + if (copy.layer - base.layer > 3) { + const layerloss = copy.layer - base.layer - 3; + result += layerloss; + copy.layer -= layerloss; + } + + for (let i = 0; i < 100; ++i) { + if (copy.lt(Decimal.dZero)) { + copy = Decimal.pow(base, copy); + result -= 1; + } else if (copy.lte(Decimal.dOne)) { + return D(result + Decimal.slog_critical(base.toNumber(), copy.toNumber())); + } else { + result += 1; + copy = Decimal.log(copy, base); + } + } + return D(result); + } + + //background info and tables of values for critical functions taken here: https://github.com/Patashu/break_eternity.js/issues/22 + public static slog_critical(base: number, height: number): number { + //TODO: for bases above 10, revert to old linear approximation until I can think of something better + if (base > 10) { + return height - 1; + } + return Decimal.critical_section(base, height, critical_slog_values); + } + + public static tetrate_critical(base: number, height: number): number { + return Decimal.critical_section(base, height, critical_tetr_values); + } + + public static critical_section(base: number, height: number, grid: number[][]): number { + //this part is simple at least, since it's just 0.1 to 0.9 + height *= 10; + if (height < 0) { + height = 0; + } + if (height > 10) { + height = 10; + } + //have to do this complicated song and dance since one of the critical_headers is Math.E, and in the future I'd like 1.5 as well + if (base < 2) { + base = 2; + } + if (base > 10) { + base = 10; + } + let lower = 0; + let upper = 0; + //basically, if we're between bases, we interpolate each bases' relevant values together + //then we interpolate based on what the fractional height is. + //accuracy could be improved by doing a non-linear interpolation (maybe), by adding more bases and heights (definitely) but this is AFAIK the best you can get without running some pari.gp or mathematica program to calculate exact values + for (let i = 0; i < critical_headers.length; ++i) { + if (critical_headers[i] == base) { + // exact match + lower = grid[i][Math.floor(height)]; + upper = grid[i][Math.ceil(height)]; + break; + } else if (critical_headers[i] < base && critical_headers[i + 1] > base) { + // interpolate between this and the next + const basefrac = + (base - critical_headers[i]) / (critical_headers[i + 1] - critical_headers[i]); + lower = + grid[i][Math.floor(height)] * (1 - basefrac) + + grid[i + 1][Math.floor(height)] * basefrac; + upper = + grid[i][Math.ceil(height)] * (1 - basefrac) + + grid[i + 1][Math.ceil(height)] * basefrac; + break; + } + } + const frac = height - Math.floor(height); + const result = lower * (1 - frac) + upper * frac; + return result; + } + + //Function for adding/removing layers from a Decimal, even fractional layers (e.g. its slog10 representation). + //Moved this over to use the same critical section as tetrate/slog. + public layeradd10(diff: DecimalSource): Decimal { + diff = Decimal.fromValue_noAlloc(diff).toNumber(); + const result = D(this); + if (diff >= 1) { + //bug fix: if result is very smol (mag < 0, layer > 0) turn it into 0 first + if (result.mag < 0 && result.layer > 0) { + result.sign = 0; + result.mag = 0; + result.layer = 0; + } else if (result.sign === -1 && result.layer == 0) { + //bug fix - for stuff like -3.layeradd10(1) we need to move the sign to the mag + result.sign = 1; + result.mag = -result.mag; + } + const layeradd = Math.trunc(diff); + diff -= layeradd; + result.layer += layeradd; + } + if (diff <= -1) { + const layeradd = Math.trunc(diff); + diff -= layeradd; + result.layer += layeradd; + if (result.layer < 0) { + for (let i = 0; i < 100; ++i) { + result.layer++; + result.mag = Math.log10(result.mag); + if (!isFinite(result.mag)) { + //another bugfix: if we hit -Infinity mag, then we should return negative infinity, not 0. 0.layeradd10(-1) h its this + if (result.sign === 0) { + result.sign = 1; + } + //also this, for 0.layeradd10(-2) + if (result.layer < 0) { + result.layer = 0; + } + return result.normalize(); + } + if (result.layer >= 0) { + break; + } + } + } + } + + while (result.layer < 0) { + result.layer++; + result.mag = Math.log10(result.mag); + } + //bugfix: before we normalize: if we started with 0, we now need to manually fix a layer ourselves! + if (result.sign === 0) { + result.sign = 1; + if (result.mag === 0 && result.layer >= 1) { + result.layer -= 1; + result.mag = 1; + } + } + result.normalize(); + + //layeradd10: like adding 'diff' to the number's slog(base) representation. Very similar to tetrate base 10 and iterated log base 10. Also equivalent to adding a fractional amount to the number's layer in its break_eternity.js representation. + if (diff !== 0) { + return result.layeradd(diff, 10); //safe, only calls positive height 1 payload tetration, slog and log + } + + return result; + } + + //layeradd: like adding 'diff' to the number's slog(base) representation. Very similar to tetrate base 'base' and iterated log base 'base'. + public layeradd(diff: number, base: DecimalSource): Decimal { + const slogthis = this.slog(base).toNumber(); + const slogdest = slogthis + diff; + if (slogdest >= 0) { + return Decimal.tetrate(base, slogdest); + } else if (!Number.isFinite(slogdest)) { + return Decimal.dNaN; + } else if (slogdest >= -1) { + return Decimal.log(Decimal.tetrate(base, slogdest + 1), base); + } else { + return Decimal.log(Decimal.log(Decimal.tetrate(base, slogdest + 2), base), base); + } + } + + //The Lambert W function, also called the omega function or product logarithm, is the solution W(x) === x*e^x. + // https://en.wikipedia.org/wiki/Lambert_W_function + //Some special values, for testing: https://en.wikipedia.org/wiki/Lambert_W_function#Special_values + public lambertw(): Decimal { + if (this.lt(-0.3678794411710499)) { + throw Error("lambertw is unimplemented for results less than -1, sorry!"); + } else if (this.mag < 0) { + return D(f_lambertw(this.toNumber())); + } else if (this.layer === 0) { + return D(f_lambertw(this.sign * this.mag)); + } else if (this.layer === 1) { + return d_lambertw(this); + } else if (this.layer === 2) { + return d_lambertw(this); + } + if (this.layer >= 3) { + return FC_NN(this.sign, this.layer - 1, this.mag); + } + + throw "Unhandled behavior in lambertw()"; + } + + //The super square-root function - what number, tetrated to height 2, equals this? + //Other sroots are possible to calculate probably through guess and check methods, this one is easy though. + // https://en.wikipedia.org/wiki/Tetration#Super-root + public ssqrt(): Decimal { + if (this.sign == 1 && this.layer >= 3) { + return FC_NN(this.sign, this.layer - 1, this.mag); + } + const lnx = this.ln(); + return lnx.div(lnx.lambertw()); + } + /* + +Unit tests for tetrate/iteratedexp/iteratedlog/layeradd10/layeradd/slog: +(note: these won't be exactly precise with the new slog implementation, but that's okay) + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var expected = first+both+1; + var result = new Decimal(10).layeradd10(first).layeradd10(both).slog(); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + first += both; + var expected = first-both+1; + var result = new Decimal(10).layeradd10(first).layeradd10(-both).slog(); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var base = Math.random()*8+2; + var expected = first+both+1; + var result = new Decimal(base).layeradd(first, base).layeradd(both, base).slog(base); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var base = Math.random()*8+2; + first += both; + var expected = first-both+1; + var result = new Decimal(base).layeradd(first, base).layeradd(-both, base).slog(base); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ +var first = Math.round((Math.random()*30))/10; +var both = Math.round((Math.random()*30))/10; +var tetrateonly = Decimal.tetrate(10, first); +var tetrateandlog = Decimal.tetrate(10, first+both).iteratedlog(10, both); +if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) +{ + console.log(first + ", " + both); +} +} + +for (var i = 0; i < 1000; ++i) +{ +var first = Math.round((Math.random()*30))/10; +var both = Math.round((Math.random()*30))/10; +var base = Math.random()*8+2; +var tetrateonly = Decimal.tetrate(base, first); +var tetrateandlog = Decimal.tetrate(base, first+both).iteratedlog(base, both); +if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) +{ + console.log(first + ", " + both); +} +} + +for (var i = 0; i < 1000; ++i) +{ +var first = Math.round((Math.random()*30))/10; +var both = Math.round((Math.random()*30))/10; +var base = Math.random()*8+2; +var tetrateonly = Decimal.tetrate(base, first, base); +var tetrateandlog = Decimal.tetrate(base, first+both, base).iteratedlog(base, both); +if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) +{ + console.log(first + ", " + both); +} +} + +for (var i = 0; i < 1000; ++i) +{ + var xex = new Decimal(-0.3678794411710499+Math.random()*100); + var x = Decimal.lambertw(xex); + if (!Decimal.eq_tolerance(xex, x.mul(Decimal.exp(x)))) + { + console.log(xex); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var xex = new Decimal(-0.3678794411710499+Math.exp(Math.random()*100)); + var x = Decimal.lambertw(xex); + if (!Decimal.eq_tolerance(xex, x.mul(Decimal.exp(x)))) + { + console.log(xex); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.random() > 0.5 ? 0 : 1); + var b = Decimal.randomDecimalForTesting(Math.random() > 0.5 ? 0 : 1); + if (Math.random() > 0.5) { a = a.recip(); } + if (Math.random() > 0.5) { b = b.recip(); } + var c = a.add(b).toNumber(); + if (Number.isFinite(c) && !Decimal.eq_tolerance(c, a.toNumber()+b.toNumber())) + { + console.log(a + ", " + b); + } +} + +for (var i = 0; i < 100; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + var b = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + if (Math.random() > 0.5) { a = a.recip(); } + if (Math.random() > 0.5) { b = b.recip(); } + var c = a.mul(b).toNumber(); + if (Number.isFinite(c) && Number.isFinite(a.toNumber()) && Number.isFinite(b.toNumber()) && a.toNumber() != 0 && b.toNumber() != 0 && c != 0 && !Decimal.eq_tolerance(c, a.toNumber()*b.toNumber())) + { + console.log("Test 1: " + a + ", " + b); + } + else if (!Decimal.mul(a.recip(), b.recip()).eq_tolerance(Decimal.mul(a, b).recip())) + { + console.log("Test 3: " + a + ", " + b); + } +} + +for (var i = 0; i < 10; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + var b = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + if (Math.random() > 0.5 && a.sign !== 0) { a = a.recip(); } + if (Math.random() > 0.5 && b.sign !== 0) { b = b.recip(); } + var c = a.pow(b); + var d = a.root(b.recip()); + var e = a.pow(b.recip()); + var f = a.root(b); + + if (!c.eq_tolerance(d) && a.sign !== 0 && b.sign !== 0) + { + console.log("Test 1: " + a + ", " + b); + } + if (!e.eq_tolerance(f) && a.sign !== 0 && b.sign !== 0) + { + console.log("Test 2: " + a + ", " + b); + } +} + +for (var i = 0; i < 10; ++i) +{ + var a = Math.round(Math.random()*18-9); + var b = Math.round(Math.random()*100-50); + var c = Math.round(Math.random()*18-9); + var d = Math.round(Math.random()*100-50); + console.log("Decimal.pow(Decimal.fromMantissaExponent(" + a + ", " + b + "), Decimal.fromMantissaExponent(" + c + ", " + d + ")).toString()"); +} + +*/ + + //Pentation/pentate: The result of tetrating 'height' times in a row. An absurdly strong operator - Decimal.pentate(2, 4.28) and Decimal.pentate(10, 2.37) are already too huge for break_eternity.js! + // https://en.wikipedia.org/wiki/Pentation + public pentate(height = 2, payload: DecimalSource = FC_NN(1, 0, 1)): Decimal { + payload = D(payload); + const oldheight = height; + height = Math.trunc(height); + const fracheight = oldheight - height; + + //I have no idea if this is a meaningful approximation for pentation to continuous heights, but it is monotonic and continuous. + if (fracheight !== 0) { + if (payload.eq(Decimal.dOne)) { + ++height; + payload = new Decimal(fracheight); + } else { + if (this.eq(10)) { + payload = payload.layeradd10(fracheight); + } else { + payload = payload.layeradd(fracheight, this); + } + } + } + + for (let i = 0; i < height; ++i) { + payload = this.tetrate(payload.toNumber()); + //bail if we're NaN + if (!isFinite(payload.layer) || !isFinite(payload.mag)) { + return payload.normalize(); + } + //give up after 10 iterations if nothing is happening + if (i > 10) { + return payload; + } + } + + return payload; + } + + // trig functions! + public sin(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.sin(this.sign * this.mag)); + } + return FC_NN(0, 0, 0); + } + + public cos(): Decimal { + if (this.mag < 0) { + return Decimal.dOne; + } + if (this.layer === 0) { + return D(Math.cos(this.sign * this.mag)); + } + return FC_NN(0, 0, 0); + } + + public tan(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.tan(this.sign * this.mag)); + } + return FC_NN(0, 0, 0); + } + + public asin(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.asin(this.sign * this.mag)); + } + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + } + + public acos(): Decimal { + if (this.mag < 0) { + return D(Math.acos(this.toNumber())); + } + if (this.layer === 0) { + return D(Math.acos(this.sign * this.mag)); + } + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + } + + public atan(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.atan(this.sign * this.mag)); + } + return D(Math.atan(this.sign * 1.8e308)); + } + + public sinh(): Decimal { + return this.exp() + .sub(this.negate().exp()) + .div(2); + } + + public cosh(): Decimal { + return this.exp() + .add(this.negate().exp()) + .div(2); + } + + public tanh(): Decimal { + return this.sinh().div(this.cosh()); + } + + public asinh(): Decimal { + return Decimal.ln( + this.add( + this.sqr() + .add(1) + .sqrt() + ) + ); + } + + public acosh(): Decimal { + return Decimal.ln( + this.add( + this.sqr() + .sub(1) + .sqrt() + ) + ); + } + + public atanh(): Decimal { + if (this.abs().gte(1)) { + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + } + + return Decimal.ln(this.add(1).div(D(1).sub(this))).div(2); + } + + /** + * Joke function from Realm Grinder + */ + public ascensionPenalty(ascensions: DecimalSource): Decimal { + if (ascensions === 0) { + return this; + } + + return this.root(Decimal.pow(10, ascensions)); + } + + /** + * Joke function from Cookie Clicker. It's 'egg' + */ + public egg(): Decimal { + return this.add(9); + } + + public lessThanOrEqualTo(other: DecimalSource): boolean { + return this.cmp(other) < 1; + } + + public lessThan(other: DecimalSource): boolean { + return this.cmp(other) < 0; + } + + public greaterThanOrEqualTo(other: DecimalSource): boolean { + return this.cmp(other) > -1; + } + + public greaterThan(other: DecimalSource): boolean { + return this.cmp(other) > 0; + } + + // return Decimal; +} + +// return Decimal; diff --git a/src/lib/collapseTransition.d.ts b/src/lib/collapseTransition.d.ts new file mode 100644 index 0000000..ff06672 --- /dev/null +++ b/src/lib/collapseTransition.d.ts @@ -0,0 +1 @@ +declare module '@ivanv/vue-collapse-transition/src/CollapseTransition.vue'; diff --git a/src/lib/pixi.ts b/src/lib/pixi.ts new file mode 100644 index 0000000..9db8382 --- /dev/null +++ b/src/lib/pixi.ts @@ -0,0 +1,7 @@ +import { Application } from "@pixi/app"; +import { BatchRenderer, Renderer } from "@pixi/core"; +import { TickerPlugin } from "@pixi/ticker"; + +Application.registerPlugin(TickerPlugin); + +Renderer.registerPlugin("batch", BatchRenderer); diff --git a/src/lib/pwa-register.d.ts b/src/lib/pwa-register.d.ts new file mode 100644 index 0000000..ac20d3c --- /dev/null +++ b/src/lib/pwa-register.d.ts @@ -0,0 +1,17 @@ +declare module 'virtual:pwa-register/vue' { + import type { Ref } from 'vue' + + export interface RegisterSWOptions { + immediate?: boolean + onNeedRefresh?: () => void + onOfflineReady?: () => void + onRegistered?: (registration: ServiceWorkerRegistration | undefined) => void + onRegisterError?: (error: any) => void + } + + export function useRegisterSW(options?: RegisterSWOptions): { + needRefresh: Ref<boolean> + offlineReady: Ref<boolean> + updateServiceWorker: (reloadPage?: boolean) => Promise<void> + } + } \ No newline at end of file diff --git a/src/lib/vue-panzoom.d.ts b/src/lib/vue-panzoom.d.ts new file mode 100644 index 0000000..ec2db3e --- /dev/null +++ b/src/lib/vue-panzoom.d.ts @@ -0,0 +1 @@ +declare module 'vue-panzoom'; diff --git a/src/lib/vue-textarea-autosize.d.ts b/src/lib/vue-textarea-autosize.d.ts new file mode 100644 index 0000000..95c04d9 --- /dev/null +++ b/src/lib/vue-textarea-autosize.d.ts @@ -0,0 +1 @@ +declare module 'vue-textarea-autosize'; diff --git a/src/main.css b/src/main.css new file mode 100644 index 0000000..60188bd --- /dev/null +++ b/src/main.css @@ -0,0 +1,68 @@ +:root { + color-scheme: dark; +} + +* { + transition-duration: 0.5s; + font-family: "Roboto Mono", monospace; + font-weight: bold; + margin: auto; + text-size-adjust: none; +} + +*:focus { + outline: none; +} + +body { + overflow: hidden; + transition: none; + text-align: center; +} + +html, body, #app { + min-height: 100%; + height: 100%; +} + +h1, h2, h3, b, input { + display: inline; +} + +button { + color: black; +} + +a, +.button, +.link { + display: block; + color: var(--link); + background: none; + border: none; + cursor: pointer; + text-decoration: none; +} + +a:hover, +.button:hover, +.link:hover { + text-shadow: 5px 0 10px var(--link), + -3px 0 12px var(--link); +} + +.button:disabled { + opacity: .5; + cursor: not-allowed; +} +.button:disabled:hover { + text-shadow: none; +} + +ul { + list-style-type: none; +} + +.Vue-Toastification__toast { + margin: unset; +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..2d27dcc --- /dev/null +++ b/src/main.ts @@ -0,0 +1,79 @@ +import "@fontsource/material-icons"; +import App from "App.vue"; +import projInfo from "data/projInfo.json"; +import "game/notifications"; +import { load } from "util/save"; +import { useRegisterSW } from "virtual:pwa-register/vue"; +import type { App as VueApp } from "vue"; +import { createApp, nextTick } from "vue"; +import { useToast } from "vue-toastification"; + +declare global { + /** + * Augment the window object so the vue app and project info can be accessed from the console. + */ + interface Window { + vue: VueApp; + projInfo: typeof projInfo; + } + + /** Fix for typedoc treating import functions as taking AssertOptions instead of GlobOptions. */ + interface AssertOptions { + as: string; + } +} + +document.title = projInfo.title; +window.projInfo = projInfo; +if (projInfo.id === "") { + throw "Project ID is empty! Please select a unique ID for this project in /src/data/projInfo.json"; +} + +requestAnimationFrame(async () => { + console.log( + "%cMade in Profectus%c\nLearn more at www.moddingtree.com", + "font-weight: bold; font-size: 24px; color: #A3BE8C; background: #2E3440; padding: 4px 8px; border-radius: 8px;", + "padding: 4px;" + ); + await load(); + const { globalBus, startGameLoop } = await import("./game/events"); + + // Create Vue + const vue = (window.vue = createApp(App)); + globalBus.emit("setupVue", vue); + vue.mount("#app"); + + // Setup PWA update prompt + nextTick(() => { + const toast = useToast(); + const { updateServiceWorker } = useRegisterSW({ + onNeedRefresh() { + toast.info("New content available, click or reload to update.", { + timeout: false, + closeOnClick: false, + draggable: false, + icon: { + iconClass: "material-icons", + iconChildren: "refresh", + iconTag: "i" + }, + rtl: false, + onClick() { + updateServiceWorker(); + } + }); + }, + onOfflineReady() { + toast.info("App ready to work offline"); + }, + onRegisterError: console.warn, + onRegistered(r) { + if (r) { + setInterval(r.update, 60 * 60 * 1000); + } + } + }); + }); + + startGameLoop(); +}); diff --git a/src/util/bignum.ts b/src/util/bignum.ts new file mode 100644 index 0000000..33d180e --- /dev/null +++ b/src/util/bignum.ts @@ -0,0 +1,46 @@ +// Import Decimal and numberUtils from a different file to globally change which big num library gets used +// This way switching out big number libraries just needs to happen here, not every file that needs big numbers +import type { DecimalSource as RawDecimalSource } from "lib/break_eternity"; +import Decimal, * as numberUtils from "util/break_eternity"; + +export const { + exponentialFormat, + commaFormat, + regularFormat, + format, + formatWhole, + formatTime, + toPlaces, + formatSmall, + invertOOM +} = numberUtils; + +export type DecimalSource = RawDecimalSource; + +declare global { + /** Augment the window object so the big num functions can be access from the console. */ + interface Window { + Decimal: typeof Decimal; + exponentialFormat: (num: DecimalSource, precision: number, mantissa: boolean) => string; + commaFormat: (num: DecimalSource, precision: number) => string; + regularFormat: (num: DecimalSource, precision: number) => string; + format: (num: DecimalSource, precision?: number, small?: boolean) => string; + formatWhole: (num: DecimalSource) => string; + formatTime: (s: number) => string; + toPlaces: (x: DecimalSource, precision: number, maxAccepted: DecimalSource) => string; + formatSmall: (x: DecimalSource, precision?: number) => string; + invertOOM: (x: DecimalSource) => Decimal; + } +} +window.Decimal = Decimal; +window.exponentialFormat = exponentialFormat; +window.commaFormat = commaFormat; +window.regularFormat = regularFormat; +window.format = format; +window.formatWhole = formatWhole; +window.formatTime = formatTime; +window.toPlaces = toPlaces; +window.formatSmall = formatSmall; +window.invertOOM = invertOOM; + +export default Decimal; diff --git a/src/util/break_eternity.ts b/src/util/break_eternity.ts new file mode 100644 index 0000000..dd6aed7 --- /dev/null +++ b/src/util/break_eternity.ts @@ -0,0 +1,196 @@ +import projInfo from "data/projInfo.json"; +import type { DecimalSource } from "lib/break_eternity"; +import Decimal from "lib/break_eternity"; + +export default Decimal; + +const decimalOne = new Decimal(1); + +export function exponentialFormat(num: DecimalSource, precision: number, mantissa = true): string { + let e = Decimal.log10(num).floor(); + let m = Decimal.div(num, Decimal.pow(10, e)); + if (m.toStringWithDecimalPlaces(precision) === "10") { + m = decimalOne; + e = e.add(1); + } + const eString = e.gte(1e9) + ? format(e, Math.max(Math.max(precision, 3), projInfo.defaultDecimalsShown)) + : e.gte(10000) + ? commaFormat(e, 0) + : e.toStringWithDecimalPlaces(0); + if (mantissa) { + return m.toStringWithDecimalPlaces(precision) + "e" + eString; + } else { + return "e" + eString; + } +} + +export function commaFormat(num: DecimalSource, precision: number): string { + if (num === null || num === undefined) { + return "NaN"; + } + num = new Decimal(num); + if (num.mag < 0.001) { + return (0).toFixed(precision); + } + const init = num.toStringWithDecimalPlaces(precision); + const portions = init.split("."); + portions[0] = portions[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); + if (portions.length == 1) return portions[0]; + return portions[0] + "." + portions[1]; +} + +export function regularFormat(num: DecimalSource, precision: number): string { + if (num === null || num === undefined) { + return "NaN"; + } + num = new Decimal(num); + if (num.mag < 0.0001) { + return (0).toFixed(precision); + } + if (num.mag < 0.1 && precision !== 0) { + precision = Math.max( + Math.max(precision, num.log10().negate().ceil().toNumber()), + projInfo.defaultDecimalsShown + ); + } + return num.toStringWithDecimalPlaces(precision); +} + +const eeee1000 = new Decimal("eeee1000"); +const e100000 = new Decimal("e100000"); +const e1000 = new Decimal("e1000"); +const e9 = new Decimal(1e9); +const e6 = new Decimal(1e6); +const e3 = new Decimal(1e3); +const nearOne = new Decimal(0.98); +const thousandth = new Decimal(0.001); +const zero = new Decimal(0); +export function format(num: DecimalSource, precision?: number, small?: boolean): string { + if (precision == null) precision = projInfo.defaultDecimalsShown; + small = small ?? projInfo.defaultShowSmall; + num = new Decimal(num); + if (isNaN(num.sign) || isNaN(num.layer) || isNaN(num.mag)) { + return "NaN"; + } + if (num.sign < 0) { + return "-" + format(num.neg(), precision); + } + if (num.mag === Number.POSITIVE_INFINITY) { + return "Infinity"; + } + if (num.gte(eeee1000)) { + const slog = num.slog(); + if (slog.gte(e6)) { + return "F" + format(slog.floor()); + } else { + return ( + Decimal.pow(10, slog.sub(slog.floor())).toStringWithDecimalPlaces(3) + + "F" + + commaFormat(slog.floor(), 0) + ); + } + } else if (num.gte(e100000)) { + return exponentialFormat(num, 0, false); + } else if (num.gte(e1000)) { + return exponentialFormat(num, 0); + } else if (num.gte(e9)) { + return exponentialFormat(num, precision); + } else if (num.gte(e3)) { + return commaFormat(num, 0); + } else if (num.gte(thousandth) || !small) { + return regularFormat(num, precision); + } else if (num.eq(zero)) { + return (0).toFixed(precision); + } + + num = invertOOM(num); + if (num.lt(e1000)) { + const val = exponentialFormat(num, precision); + return val.replace(/([^(?:e|F)]*)$/, "-$1"); + } else { + return format(num, precision) + "⁻¹"; + } +} + +export function formatWhole(num: DecimalSource): string { + num = new Decimal(num); + if (num.sign < 0) { + return "-" + formatWhole(num.neg()); + } + if (num.gte(e9)) { + return format(num); + } + if (num.lte(nearOne) && !num.eq(zero)) { + return format(num); + } + return format(num, 0); +} + +export function formatTime(seconds: DecimalSource): string { + if (Decimal.lt(seconds, 0)) { + return "-" + formatTime(Decimal.neg(seconds)); + } + if (Decimal.gt(seconds, 2 ** 51)) { + // integer precision limit + return format(Decimal.div(seconds, 31536000)) + "y"; + } + seconds = new Decimal(seconds).toNumber(); + if (seconds < 60) { + return format(seconds) + "s"; + } else if (seconds < 3600) { + return formatWhole(Math.floor(seconds / 60)) + "m " + format(seconds % 60) + "s"; + } else if (seconds < 86400) { + return ( + formatWhole(Math.floor(seconds / 3600)) + + "h " + + formatWhole(Math.floor(seconds / 60) % 60) + + "m " + + formatWhole(seconds % 60) + + "s" + ); + } else if (seconds < 31536000) { + return ( + formatWhole(Math.floor(seconds / 84600) % 365) + + "d " + + formatWhole(Math.floor(seconds / 3600) % 24) + + "h " + + formatWhole(Math.floor(seconds / 60) % 60) + + "m" + ); + } else { + return ( + formatWhole(Math.floor(seconds / 31536000)) + + "y " + + formatWhole(Math.floor(seconds / 84600) % 365) + + "d " + + formatWhole(Math.floor(seconds / 3600) % 24) + + "h" + ); + } +} + +export function toPlaces(x: DecimalSource, precision: number, maxAccepted: DecimalSource): string { + x = new Decimal(x); + let result = x.toStringWithDecimalPlaces(precision); + if (new Decimal(result).gte(maxAccepted)) { + result = Decimal.sub(maxAccepted, Math.pow(0.1, precision)).toStringWithDecimalPlaces( + precision + ); + } + return result; +} + +// Will also display very small numbers +export function formatSmall(x: DecimalSource, precision?: number): string { + return format(x, precision, true); +} + +export function invertOOM(x: DecimalSource): Decimal { + let e = Decimal.log10(x).ceil(); + const m = Decimal.div(x, Decimal.pow(10, e)); + e = e.neg(); + x = new Decimal(10).pow(e).times(m); + + return x; +} diff --git a/src/util/common.ts b/src/util/common.ts new file mode 100644 index 0000000..d7560dd --- /dev/null +++ b/src/util/common.ts @@ -0,0 +1,27 @@ +export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] }; + +export type ArrayElements<T extends ReadonlyArray<unknown>> = T extends ReadonlyArray<infer S> + ? S + : never; + +// Reference: +// https://stackoverflow.com/questions/7225407/convert-camelcasetext-to-sentence-case-text +export function camelToTitle(camel: string): string { + let title = camel.replace(/([A-Z])/g, " $1"); + title = title.charAt(0).toUpperCase() + title.slice(1); + return title; +} + +export function isFunction<T, S extends ReadonlyArray<unknown>, R>( + functionOrValue: ((...args: S) => T) | R +): functionOrValue is (...args: S) => T { + return typeof functionOrValue === "function"; +} + +export enum Direction { + Up = "Up", + Down = "Down", + Left = "Left", + Right = "Right", + Default = "Up" +} diff --git a/src/util/computed.ts b/src/util/computed.ts new file mode 100644 index 0000000..59db8ab --- /dev/null +++ b/src/util/computed.ts @@ -0,0 +1,55 @@ +import type { Ref } from "vue"; +import { computed } from "vue"; +import { isFunction } from "util/common"; + +export const DoNotCache = Symbol("DoNotCache"); + +export type Computable<T> = T | Ref<T> | (() => T); +export type ProcessedComputable<T> = T | Ref<T>; +export type GetComputableType<T> = T extends { [DoNotCache]: true } + ? T + : T extends () => infer S + ? Ref<S> + : undefined extends T + ? undefined + : T; +export type GetComputableTypeWithDefault<T, S> = undefined extends T + ? S + : GetComputableType<NonNullable<T>>; +export type UnwrapComputableType<T> = T extends Ref<infer S> ? S : T extends () => infer S ? S : T; + +export type ComputableKeysOf<T> = Pick< + T, + { + [K in keyof T]: T[K] extends Computable<unknown> ? K : never; + }[keyof T] +>; + +// TODO fix the typing of this function, such that casting isn't necessary and can be used to +// detect if a createX function is validly written +export function processComputable<T, S extends keyof ComputableKeysOf<T>>( + obj: T, + key: S +): asserts obj is T & { [K in S]: ProcessedComputable<UnwrapComputableType<T[S]>> } { + const computable = obj[key]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (isFunction(computable) && computable.length === 0 && !(computable as any)[DoNotCache]) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + obj[key] = computed(computable.bind(obj)); + } else if (isFunction(computable)) { + obj[key] = computable.bind(obj) as T[S]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (obj[key] as any)[DoNotCache] = true; + } +} + +export function convertComputable<T>(obj: Computable<T>): ProcessedComputable<T> { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (isFunction(obj) && !(obj as any)[DoNotCache]) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + obj = computed(obj); + } + return obj as ProcessedComputable<T>; +} diff --git a/src/util/proxies.ts b/src/util/proxies.ts new file mode 100644 index 0000000..a41b8d1 --- /dev/null +++ b/src/util/proxies.ts @@ -0,0 +1,65 @@ +import Decimal from "util/bignum"; + +export const ProxyState = Symbol("ProxyState"); +export const ProxyPath = Symbol("ProxyPath"); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type ProxiedWithState<T> = NonNullable<T> extends Record<PropertyKey, any> + ? NonNullable<T> extends Decimal + ? T + : { + [K in keyof T]: ProxiedWithState<T[K]>; + } & { + [ProxyState]: T; + [ProxyPath]: string[]; + } + : T; + +// Takes a function that returns an object and pretends to be that object +// Note that the object is lazily calculated +export function createLazyProxy<T extends object, S extends T>( + objectFunc: (baseObject: S) => T & S, + baseObject: S = {} as S +): T { + const obj: S & Partial<T> = baseObject; + let calculated = false; + function calculateObj(): T { + if (!calculated) { + Object.assign(obj, objectFunc(obj)); + calculated = true; + } + return obj as S & T; + } + + return new Proxy(obj, { + get(target, key) { + if (key === ProxyState) { + return calculateObj(); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (calculateObj() as any)[key]; + }, + set(target, key, value) { + // TODO give warning about this? It should only be done with caution + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (calculateObj() as any)[key] = value; + return true; + }, + has(target, key) { + if (key === ProxyState) { + return true; + } + return Reflect.has(calculateObj(), key); + }, + ownKeys() { + return Reflect.ownKeys(calculateObj()); + }, + getOwnPropertyDescriptor(target, key) { + if (!calculated) { + Object.assign(obj, objectFunc(obj)); + calculated = true; + } + return Object.getOwnPropertyDescriptor(target, key); + } + }) as S & T; +} diff --git a/src/util/save.ts b/src/util/save.ts new file mode 100644 index 0000000..4138e17 --- /dev/null +++ b/src/util/save.ts @@ -0,0 +1,143 @@ +import projInfo from "data/projInfo.json"; +import { globalBus } from "game/events"; +import type { Player, PlayerData } from "game/player"; +import player, { stringifySave } from "game/player"; +import settings, { loadSettings } from "game/settings"; +import LZString from "lz-string"; +import { ProxyState } from "util/proxies"; + +export function setupInitialStore(player: Partial<PlayerData> = {}): Player { + return Object.assign( + { + id: `${projInfo.id}-0`, + name: "Default Save", + tabs: projInfo.initialTabs.slice(), + time: Date.now(), + autosave: true, + offlineProd: true, + offlineTime: 0, + timePlayed: 0, + keepGoing: false, + modID: projInfo.id, + modVersion: projInfo.versionNumber, + layers: {} + }, + player + ) as Player; +} + +export function save(playerData?: PlayerData): string { + const stringifiedSave = LZString.compressToUTF16( + stringifySave(playerData ?? player[ProxyState]) + ); + localStorage.setItem((playerData ?? player[ProxyState]).id, stringifiedSave); + return stringifiedSave; +} + +export async function load(): Promise<void> { + // Load global settings + loadSettings(); + + try { + let save = localStorage.getItem(settings.active); + if (save == null) { + await loadSave(newSave()); + return; + } + if (save[0] === "{") { + // plaintext. No processing needed + } else if (save[0] === "e") { + // Assumed to be base64, which starts with e + save = decodeURIComponent(escape(atob(save))); + } else if (save[0] === "ᯡ") { + // Assumed to be lz, which starts with ᯡ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + save = LZString.decompressFromUTF16(save)!; + } else { + throw `Unable to determine save encoding`; + } + const player = JSON.parse(save); + if (player.modID !== projInfo.id) { + await loadSave(newSave()); + return; + } + player.id = settings.active; + await loadSave(player); + } catch (e) { + console.error("Failed to load save. Falling back to new save.\n", e); + await loadSave(newSave()); + } +} + +export function newSave(): PlayerData { + const id = getUniqueID(); + const player = setupInitialStore({ id }); + save(player); + + settings.saves.push(id); + + return player; +} + +export function getUniqueID(): string { + let id, + i = 0; + do { + id = `${projInfo.id}-${i++}`; + } while (localStorage.getItem(id)); + return id; +} + +export async function loadSave(playerObj: Partial<PlayerData>): Promise<void> { + console.info("Loading save", playerObj); + const { layers, removeLayer, addLayer } = await import("game/layers"); + const { fixOldSave, getInitialLayers } = await import("data/projEntry"); + + for (const layer in layers) { + const l = layers[layer]; + if (l) { + removeLayer(l); + } + } + getInitialLayers(playerObj).forEach(layer => addLayer(layer, playerObj)); + + playerObj = setupInitialStore(playerObj); + if (playerObj.offlineProd && playerObj.time) { + if (playerObj.offlineTime == undefined) playerObj.offlineTime = 0; + playerObj.offlineTime += (Date.now() - playerObj.time) / 1000; + } + playerObj.time = Date.now(); + if (playerObj.modVersion !== projInfo.versionNumber) { + fixOldSave(playerObj.modVersion, playerObj); + } + + Object.assign(player, playerObj); + settings.active = player.id; + + globalBus.emit("onLoad"); +} + +setInterval(() => { + if (player.autosave) { + save(); + } +}, 1000); +window.onbeforeunload = () => { + if (player.autosave) { + save(); + } +}; + +declare global { + /** + * Augment the window object so the save function, and the hard reset function can be access from the console. + */ + interface Window { + save: VoidFunction; + hardReset: VoidFunction; + } +} +window.save = save; +export const hardReset = (window.hardReset = async () => { + await loadSave(newSave()); +}); diff --git a/src/util/vue.tsx b/src/util/vue.tsx new file mode 100644 index 0000000..8b8bf09 --- /dev/null +++ b/src/util/vue.tsx @@ -0,0 +1,236 @@ +import Col from "components/layout/Column.vue"; +import Row from "components/layout/Row.vue"; +import type { CoercableComponent, GenericComponent, JSXFunction } from "features/feature"; +import { Component as ComponentKey, GatherProps, jsx, Visibility } from "features/feature"; +import type { ProcessedComputable } from "util/computed"; +import { DoNotCache } from "util/computed"; +import type { Component, ComputedRef, DefineComponent, PropType, Ref, ShallowRef } from "vue"; +import { + computed, + defineComponent, + isRef, + onUnmounted, + ref, + shallowRef, + unref, + watchEffect +} from "vue"; + +export function coerceComponent( + component: CoercableComponent, + defaultWrapper = "span" +): DefineComponent { + if (typeof component === "function") { + return defineComponent({ render: component }); + } + if (typeof component === "string") { + if (component.length > 0) { + component = component.trim(); + if (component.charAt(0) !== "<") { + component = `<${defaultWrapper}>${component}</${defaultWrapper}>`; + } + + return defineComponent({ template: component }); + } + return defineComponent({ render: () => ({}) }); + } + return component; +} + +export interface VueFeature { + [ComponentKey]: GenericComponent; + [GatherProps]: () => Record<string, unknown>; +} + +export function render(object: VueFeature | CoercableComponent): JSX.Element | DefineComponent { + if (isCoercableComponent(object)) { + if (typeof object === "function") { + return (object as JSXFunction)(); + } + return coerceComponent(object); + } + const Component = object[ComponentKey]; + return <Component {...object[GatherProps]()} />; +} + +export function renderRow(...objects: (VueFeature | CoercableComponent)[]): JSX.Element { + return <Row>{objects.map(render)}</Row>; +} + +export function renderCol(...objects: (VueFeature | CoercableComponent)[]): JSX.Element { + return <Col>{objects.map(render)}</Col>; +} + +export function renderJSX(object: VueFeature | CoercableComponent): JSX.Element { + if (isCoercableComponent(object)) { + if (typeof object === "function") { + return (object as JSXFunction)(); + } + if (typeof object === "string") { + return <>{object}</>; + } + // TODO why is object typed as never? + const Comp = object as DefineComponent; + return <Comp />; + } + const Component = object[ComponentKey]; + return <Component {...object[GatherProps]()} />; +} + +export function renderRowJSX(...objects: (VueFeature | CoercableComponent)[]): JSX.Element { + return <Row>{objects.map(renderJSX)}</Row>; +} + +export function renderColJSX(...objects: (VueFeature | CoercableComponent)[]): JSX.Element { + return <Col>{objects.map(renderJSX)}</Col>; +} + +export function joinJSX(objects: JSX.Element[], joiner: JSX.Element): JSX.Element { + return objects.reduce((acc, curr) => ( + <> + {acc} + {joiner} + {curr} + </> + )); +} + +export function isCoercableComponent(component: unknown): component is CoercableComponent { + if (typeof component === "string") { + return true; + } else if (typeof component === "object") { + if (component == null) { + return false; + } + return "render" in component || "component" in component; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } else if (typeof component === "function" && (component as any)[DoNotCache] === true) { + return true; + } + return false; +} + +export function setupHoldToClick( + onClick?: Ref<((e?: MouseEvent | TouchEvent) => void) | undefined>, + onHold?: Ref<VoidFunction | undefined> +): { + start: (e: MouseEvent | TouchEvent) => void; + stop: VoidFunction; + handleHolding: VoidFunction; +} { + const interval = ref<NodeJS.Timer | null>(null); + const event = ref<MouseEvent | TouchEvent | undefined>(undefined); + + function start(e: MouseEvent | TouchEvent) { + if (!interval.value) { + interval.value = setInterval(handleHolding, 250); + } + event.value = e; + } + function stop() { + if (interval.value) { + clearInterval(interval.value); + interval.value = null; + } + } + function handleHolding() { + if (onHold && onHold.value) { + onHold.value(); + } else if (onClick && onClick.value) { + onClick.value(event.value); + } + } + + onUnmounted(stop); + + return { start, stop, handleHolding }; +} + +export function getFirstFeature< + T extends VueFeature & { visibility: ProcessedComputable<Visibility> } +>( + features: T[], + filter: (feature: T) => boolean +): { + firstFeature: Ref<T | undefined>; + collapsedContent: JSXFunction; + hasCollapsedContent: Ref<boolean>; +} { + const filteredFeatures = computed(() => + features.filter( + feature => unref(feature.visibility) === Visibility.Visible && filter(feature) + ) + ); + return { + firstFeature: computed(() => filteredFeatures.value[0]), + collapsedContent: jsx(() => renderCol(...filteredFeatures.value.slice(1))), + hasCollapsedContent: computed(() => filteredFeatures.value.length > 1) + }; +} + +export function computeComponent( + component: Ref<ProcessedComputable<CoercableComponent>>, + defaultWrapper = "div" +): ShallowRef<Component | ""> { + const comp = shallowRef<Component | "">(); + watchEffect(() => { + comp.value = coerceComponent(unwrapRef(component), defaultWrapper); + }); + return comp as ShallowRef<Component | "">; +} +export function computeOptionalComponent( + component: Ref<ProcessedComputable<CoercableComponent | undefined> | undefined>, + defaultWrapper = "div" +): ShallowRef<Component | "" | null> { + const comp = shallowRef<Component | "" | null>(null); + watchEffect(() => { + const currComponent = unwrapRef(component); + comp.value = currComponent == null ? null : coerceComponent(currComponent, defaultWrapper); + }); + return comp; +} + +export function wrapRef<T>(ref: Ref<ProcessedComputable<T>>): ComputedRef<T> { + return computed(() => unwrapRef(ref)); +} + +export function unwrapRef<T>(ref: Ref<ProcessedComputable<T>>): T { + return unref<T>(unref(ref)); +} + +export function setRefValue<T>(ref: Ref<T | Ref<T>>, value: T) { + if (isRef(ref.value)) { + ref.value.value = value; + } else { + ref.value = value; + } +} + +export type PropTypes = + | typeof Boolean + | typeof String + | typeof Number + | typeof Function + | typeof Object + | typeof Array; +// TODO Unfortunately, the typescript engine gives up on typing completely when you use this method, +// Even though it has the same typing as when doing it manually +export function processedPropType<T>(...types: PropTypes[]): PropType<ProcessedComputable<T>> { + if (!types.includes(Object)) { + types.push(Object); + } + return types as PropType<ProcessedComputable<T>>; +} + +export function trackHover(element: VueFeature): Ref<boolean> { + const isHovered = ref(false); + + const elementGatherProps = element[GatherProps].bind(element); + element[GatherProps] = () => ({ + ...elementGatherProps(), + onPointerenter: () => (isHovered.value = true), + onPointerleave: () => (isHovered.value = false) + }); + + return isHovered; +} diff --git a/tests/util/common.test.ts b/tests/util/common.test.ts new file mode 100644 index 0000000..619810f --- /dev/null +++ b/tests/util/common.test.ts @@ -0,0 +1,27 @@ +import { camelToTitle, isFunction } from "util/common"; +import { describe, expect, test, vi } from "vitest"; + +describe("camelToTitle", () => { + test("Capitalizes first letter in single word", () => + expect(camelToTitle("test")).toBe("Test")); + + test("Converts three word camel case string to title case", () => + expect(camelToTitle("camelCaseTest")).toBe("Camel Case Test")); +}); + +describe("isFunction", () => { + test("Given function returns true", () => expect(isFunction(vi.fn())).toBe(true)); + + // Go through all primitives and basic types + test("Given a non-function returns false", () => { + expect(isFunction("test")).toBe(false); + expect(isFunction(10)).toBe(false); + expect(isFunction(BigInt(10))).toBe(false); + expect(isFunction(true)).toBe(false); + expect(isFunction(undefined)).toBe(false); + expect(isFunction(Symbol())).toBe(false); + expect(isFunction(null)).toBe(false); + expect(isFunction({})).toBe(false); + expect(isFunction([])).toBe(false); + }); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..280a1e1 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,50 @@ +{ + "compilerOptions": { + "noErrorTruncation": true, + "target": "esnext", + "module": "esnext", + "strict": true, + "checkJs": false, + "jsx": "preserve", + "importHelpers": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "experimentalDecorators": true, + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "baseUrl": "src", + "types": [ + "vite/client", + "node" + ], + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.vue", + "tests/**/*.ts", + "tests/**/*.tsx" + ], + "exclude": [ + "node_modules" + ], + "typedocOptions": { + "entryPoints": ["src"], + "entryPointStrategy": "expand", + "cleanOutputDir": true, + "name": "Profectus", + "includeVersion": true, + "categorizeByGroup": false, + "readme": "none", + "out": "../docs/api" + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..080d8e6 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,64 @@ +import vue from "@vitejs/plugin-vue"; +import vueJsx from "@vitejs/plugin-vue-jsx"; +import { defineConfig } from "vite"; +import { VitePWA } from "vite-plugin-pwa"; +import tsconfigPaths from "vite-tsconfig-paths"; +import projInfo from "./src/data/projInfo.json"; + +// https://vitejs.dev/config/ +export default defineConfig({ + base: "./", + build: { + rollupOptions: { + output: { + manualChunks(id) { + if (id.includes("node_modules")) { + return id.toString().split("node_modules/")[1].split("/")[0].toString(); + } + } + } + } + }, + resolve: { + alias: { + vue: "vue/dist/vue.esm-bundler.js" + } + }, + plugins: [ + vue(), + vueJsx({ + // options are passed on to @vue/babel-plugin-jsx + }), + tsconfigPaths(), + VitePWA({ + includeAssets: ["Logo.svg", "favicon.ico", "robots.txt", "apple-touch-icon.png"], + manifest: { + name: projInfo.title, + short_name: projInfo.title, + description: projInfo.description, + theme_color: "#2E3440", + icons: [ + { + src: "pwa-192x192.png", + sizes: "192x192", + type: "image/png" + }, + { + src: "pwa-512x512.png", + sizes: "512x512", + type: "image/png" + }, + { + src: "pwa-512x512.png", + sizes: "512x512", + type: "image/png", + purpose: "any maskable" + } + ] + } + }) + ], + test: { + environment: "jsdom" + } +});