diff --git a/.babelrc.json b/.babelrc.json index 0a5a8a69..0823833d 100644 --- a/.babelrc.json +++ b/.babelrc.json @@ -14,4 +14,4 @@ "@babel/preset-typescript" ], "plugins": [] -} \ No newline at end of file +} diff --git a/.eslintignore b/.eslintignore index 3ed3bbec..93036be0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,13 @@ -site/ -scripts/apidocs.js -scripts/release.js -karma.conf.js +/site +/sandbox +/scripts +karma.conf.* webpack.config.js webpack.config.prod.js -version.js \ No newline at end of file +wallaby.js +version.js +node_modules +build +coverage +node_cache +*.d.ts diff --git a/.eslintrc.json b/.eslintrc.json index d4597771..b71322f7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,67 +3,57 @@ "browser": true, "node": true }, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": [ - "./src/**/tsconfig.json" - ], - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint", - "jsdoc" - ], - "extends": [ - "plugin:jsdoc/recommended", - "prettier", - "plugin:storybook/recommended" + "plugins": ["@typescript-eslint", "jsdoc"], + "extends": ["plugin:jsdoc/recommended", "plugin:storybook/recommended", "prettier"], + "overrides": [ + // javascript parser + { + "files": ["*.js", "*.jsx"], + // we can still use the typescript parser for javascript files + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module", + "project": false + } + }, + // typescript parser + { + "files": ["*.ts", "*.tsx"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module", + "project": true + } + } ], "rules": { "@typescript-eslint/naming-convention": [ "error", { "selector": "class", - "format": [ - "PascalCase" - ] + "format": ["PascalCase"] }, { "selector": "memberLike", - "modifiers": [ - "private", - "static" - ], - "format": [ - "UPPER_CASE" - ], + "modifiers": ["private", "static"], + "format": ["UPPER_CASE"], "leadingUnderscore": "require" }, { "selector": "memberLike", - "modifiers": [ - "private" - ], - "format": [ - "camelCase" - ], + "modifiers": ["private"], + "format": ["camelCase"], "leadingUnderscore": "require" }, { "selector": "interface", - "format": [ - "PascalCase" - ], + "format": ["PascalCase"], "custom": { "regex": "^I[A-Z]", "match": false } } ], - "@typescript-eslint/indent": [ - "error", - 2 - ], "@typescript-eslint/no-empty-function": "error", "curly": "error", "dot-notation": "error", @@ -71,20 +61,7 @@ "no-console": [ "error", { - "allow": [ - "debug", - "info", - "time", - "timeEnd", - "trace" - ] - } - ], - "quotes": [ - "error", - "single", - { - "allowTemplateLiterals": true + "allow": ["debug", "info", "time", "timeEnd", "trace"] } ], "no-debugger": "error", @@ -97,37 +74,15 @@ "prefer-const": "error", "require-await": "warn", "radix": "error", - "max-len": [ - "error", - { - "code": 140 - } - ], - "semi": [ - "error", - "always" - ], - "comma-dangle": [ - "error", - "never" - ], - "no-trailing-spaces": "error", - "eqeqeq": [ - "error", - "smart" - ], + "eqeqeq": ["error", "smart"], "no-irregular-whitespace": "error", - "brace-style": [ - "error", - "1tbs" - ], + "brace-style": ["error", "1tbs"], "no-unused-expressions": [ "error", { "allowTernary": true } ], - "keyword-spacing": "error", "jsdoc/require-param": 0, "jsdoc/require-param-description": 0, "jsdoc/require-param-type": 0, @@ -138,16 +93,7 @@ "jsdoc/check-tag-names": [ "error", { - "definedTags": [ - "hidden", - "internal", - "source", - "obsolete", - "warning", - "notimplemented", - "credit", - "typedoc" - ] + "definedTags": ["hidden", "internal", "source", "obsolete", "warning", "notimplemented", "credit", "typedoc"] } ] } diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..3d04c1a9 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +9223608d57af6efe3205baa924c16b8f4788bd5b +3cf93825d0a90e93651f058bfd200df0c43f47db \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 81cc147c..fd36c158 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,4 +2,4 @@ blank_issues_enabled: false contact_links: - name: Excalibur Discord Link url: https://discord.gg/W6zUd4tTY3 - about: Join the Excalibur Discord and come chat about making video games! \ No newline at end of file + about: Join the Excalibur Discord and come chat about making video games! diff --git a/.github/pr-labeler.yml b/.github/pr-labeler.yml index 3e2c8e4f..4e704149 100644 --- a/.github/pr-labeler.yml +++ b/.github/pr-labeler.yml @@ -1,3 +1,3 @@ enhancement: ['feature/*', 'feat/*', 'enhancement/*'] bug: ['fix/*', 'bug/*'] -chore: chore/* \ No newline at end of file +chore: chore/* diff --git a/.github/workflows/browsersupport.yml b/.github/workflows/browsersupport.yml index 8eefcc7c..f0a20df7 100644 --- a/.github/workflows/browsersupport.yml +++ b/.github/workflows/browsersupport.yml @@ -4,21 +4,21 @@ env: BS_PASSWORD: ${{ secrets.BS_PASSWORD }} on: push: - branches: [ main ] + branches: [main] jobs: browser_support: runs-on: [ubuntu-latest] timeout-minutes: 15 steps: - - uses: actions/checkout@v4 - with: - submodules: true - fetch-depth: 100 - - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - registry-url: 'https://registry.npmjs.org' - cache: npm - - run: npm ci - - run: npm run browserstack + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 100 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' + cache: npm + - run: npm ci + - run: npm run browserstack diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 829767b4..c4ac360b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,14 +5,14 @@ name: CI env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - COVERALLS_REPO_TOKEN: "${{ secrets.COVERALLS_REPO_TOKEN }}" - COVERALLS_GIT_BRANCH: "${{ github.ref }}" + COVERALLS_REPO_TOKEN: '${{ secrets.COVERALLS_REPO_TOKEN }}' + COVERALLS_GIT_BRANCH: '${{ github.ref }}' on: pull_request: - branches: [ main ] + branches: [main] push: - branches: [ main ] + branches: [main] workflow_call: jobs: @@ -20,55 +20,54 @@ jobs: runs-on: [ubuntu-latest] steps: - - uses: actions/checkout@v4 - with: - submodules: true - fetch-depth: 100 - - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - registry-url: 'https://registry.npmjs.org' - cache: npm - - run: npm ci - - run: npm run linux:ci - - name: Coveralls - uses: coverallsapp/github-action@v2.2.3 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 100 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' + cache: npm + - run: npm ci + - run: npm run linux:ci + - name: Coveralls + uses: coverallsapp/github-action@v2.2.3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + typedoc: runs-on: [ubuntu-latest] env: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true - + steps: - - uses: actions/checkout@v4 - with: - submodules: true - fetch-depth: 100 - - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - cache: npm - registry-url: 'https://registry.npmjs.org' - - run: npm ci --ignore-scripts - - run: npm run apidocs + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 100 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: npm + registry-url: 'https://registry.npmjs.org' + - run: npm ci --ignore-scripts + - run: npm run apidocs examples: runs-on: [ubuntu-latest] env: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true - - steps: - - uses: actions/checkout@v4 - with: - submodules: true - fetch-depth: 100 - - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - cache: npm - registry-url: 'https://registry.npmjs.org' - - run: npm ci --ignore-scripts - - run: npm run build-storybook + steps: + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 100 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: npm + registry-url: 'https://registry.npmjs.org' + - run: npm ci --ignore-scripts + - run: npm run build-storybook diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f015d31d..13a66bf5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,7 +1,7 @@ name: Deploy on: push: - branches: [ main ] + branches: [main] env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -16,31 +16,30 @@ jobs: runs-on: [ubuntu-latest] steps: - - uses: actions/checkout@v4 - with: - submodules: true - fetch-depth: 100 - - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - registry-url: 'https://registry.npmjs.org' - cache: npm - - run: npm ci - - run: npm run build - - run: npm run build:esm - - run: echo "alpha_version=$(node -e "console.log(require('./version').getAlphaVersion());")" >> $GITHUB_ENV - - run: echo $alpha_version - - run: npm --no-git-tag-version version $alpha_version - - run: npm publish --tag next - - name: Create Tag - uses: actions/github-script@v7.0.1 - with: - script: | - const {alpha_version} = process.env; - github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: `refs/tags/${alpha_version}`, - sha: context.sha - }) - + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 100 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' + cache: npm + - run: npm ci + - run: npm run build + - run: npm run build:esm + - run: echo "alpha_version=$(node -e "console.log(require('./version').getAlphaVersion());")" >> $GITHUB_ENV + - run: echo $alpha_version + - run: npm --no-git-tag-version version $alpha_version + - run: npm publish --tag next + - name: Create Tag + uses: actions/github-script@v7.0.1 + with: + script: | + const {alpha_version} = process.env; + github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `refs/tags/${alpha_version}`, + sha: context.sha + }) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cc252e72..5a46612a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,7 @@ env: release: true GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - + jobs: build: uses: ./.github/workflows/build.yml @@ -17,16 +17,16 @@ jobs: runs-on: [ubuntu-latest] steps: - - uses: actions/checkout@v4 - with: - submodules: true - fetch-depth: 100 - - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - registry-url: 'https://registry.npmjs.org' - cache: npm - - run: npm ci - - run: npm run build - - run: npm run build:esm - - run: npm publish + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 100 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' + cache: npm + - run: npm ci + - run: npm run build + - run: npm run build:esm + - run: npm publish diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index ca49b2d3..5c2cbe0f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,20 +2,19 @@ name: Mark stale issues and pull requests on: schedule: - - cron: "0 0 * * *" + - cron: '0 0 * * *' jobs: stale: - runs-on: ubuntu-latest - + steps: - - uses: actions/stale@v8 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-close: -1 - exempt-issue-labels: good first issue,help wanted,on-deck - stale-issue-message: "This issue hasn't had any recent activity lately and is being marked as stale automatically." - stale-pr-message: "This PR hasn't had any recent activity lately and is being marked as stale automatically." - stale-issue-label: 'stale' - stale-pr-label: 'stale' + - uses: actions/stale@v8 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-close: -1 + exempt-issue-labels: good first issue,help wanted,on-deck + stale-issue-message: "This issue hasn't had any recent activity lately and is being marked as stale automatically." + stale-pr-message: "This PR hasn't had any recent activity lately and is being marked as stale automatically." + stale-issue-label: 'stale' + stale-pr-label: 'stale' diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.prettierignore b/.prettierignore index cbddd611..020f9187 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,10 @@ -karma.conf.js +karma.conf.* package.json -package-lock.json \ No newline at end of file +package-lock.json +node_modules +build +coverage +node_cache +/site +*.md +*.mdx \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..26274202 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 140, + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "none" +} diff --git a/.storybook/manager.js b/.storybook/manager.js index 07e1e35b..63a25abb 100644 --- a/.storybook/manager.js +++ b/.storybook/manager.js @@ -1,7 +1,6 @@ import { addons } from '@storybook/addons'; addons.setConfig({ - // Excalibur will be listening for all key events enableShortcuts: false -}) \ No newline at end of file +}); diff --git a/docker-compose.yml b/docker-compose.yml index f78cd4c2..8eab9ae7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: context: . dockerfile: docker/Dockerfile working_dir: /opt/app - container_name: "dev" + container_name: 'dev' volumes: - - "./:/opt/app" - - /opt/app/node_modules \ No newline at end of file + - './:/opt/app' + - /opt/app/node_modules diff --git a/package-lock.json b/package-lock.json index fb82045e..1195527e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "eslint-plugin-jsdoc": "48.2.2", "eslint-plugin-storybook": "0.8.0", "excalibur-jasmine": "0.3.4", + "husky": "9.0.11", "istanbul": "0.4.5", "istanbul-instrumenter-loader": "3.0.1", "jasmine": "5.1.0", @@ -53,6 +54,8 @@ "karma-spec-reporter": "0.0.36", "karma-summary-reporter": "3.1.1", "karma-webpack": "5.0.1", + "lint-staged": "15.2.2", + "prettier": "3.2.5", "puppeteer": "15.5.0", "raw-loader": "4.0.2", "react": "18.2.0", @@ -4924,6 +4927,21 @@ "node": ">=8" } }, + "node_modules/@storybook/cli/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@storybook/cli/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5004,6 +5022,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@storybook/codemod/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@storybook/codemod/node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -7435,6 +7468,18 @@ "string-width": "^4.1.0" } }, + "node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -8784,6 +8829,72 @@ "@colors/colors": "1.5.0" } }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/clipboardy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", @@ -11777,6 +11888,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", @@ -12422,6 +12545,21 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true, + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -14243,12 +14381,337 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/lint-staged": { + "version": "15.2.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.2.tgz", + "integrity": "sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==", + "dev": true, + "dependencies": { + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.1", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/lint-staged/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/listr2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz", + "integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -14394,6 +14857,166 @@ "node": ">=8" } }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/log4js": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz", @@ -15731,6 +16354,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -15926,15 +16561,15 @@ } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -17839,6 +18474,46 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/socket.io": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", @@ -18165,6 +18840,15 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -23580,6 +24264,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -23645,6 +24335,12 @@ "slash": "^3.0.0" } }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true + }, "type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -25522,6 +26218,12 @@ "string-width": "^4.1.0" } }, + "ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true + }, "ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -26550,6 +27252,50 @@ "string-width": "^4.2.0" } }, + "cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "requires": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, "clipboardy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", @@ -28782,6 +29528,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true + }, "get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", @@ -29269,6 +30021,12 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -30637,12 +31395,219 @@ "type-check": "~0.3.2" } }, + "lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true + }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "lint-staged": { + "version": "15.2.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.2.tgz", + "integrity": "sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==", + "dev": true, + "requires": { + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.1", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" + }, + "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + }, + "commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + }, + "yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true + } + } + }, + "listr2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz", + "integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==", + "dev": true, + "requires": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "requires": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "requires": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + } + } + } + }, "loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -30748,6 +31713,108 @@ } } }, + "log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "requires": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "requires": { + "restore-cursor": "^4.0.0" + } + }, + "emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "requires": { + "get-east-asian-width": "^1.0.0" + } + }, + "restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "requires": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + } + }, + "string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "requires": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "requires": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + } + } + } + }, "log4js": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz", @@ -31760,6 +32827,12 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -31887,9 +32960,9 @@ "dev": true }, "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true }, "pretty-error": { @@ -33308,6 +34381,30 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true + } + } + }, "socket.io": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", @@ -33562,6 +34659,12 @@ "safe-buffer": "~5.1.0" } }, + "string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", diff --git a/package.json b/package.json index 26f19b52..4e6765d8 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "simple" ], "scripts": { - "all": "npm run lint && npm run core && npm run build:esm && npm run test && npm run legacy-visual", - "all:ci": "npm run lint && npm run core && npm run build:esm && npm run test:ci && npm run legacy-visual", + "all": "npm run format && npm run lint && npm run core && npm run build:esm && npm run test && npm run legacy-visual", + "all:ci": "npm run format && npm run lint && npm run core && npm run build:esm && npm run test:ci && npm run legacy-visual", "clean": "rimraf .tsbuildinfo ./build/dist ./build ./src/spec/*.js ./src/spec/*.map", "linux:ci": "npm run clean && npm run all:ci && npm run coveralls && npm run apidocs", "appveyor": "npm run all:ci && npm run nuget 0.0.1", @@ -43,11 +43,11 @@ "core:bundle": "webpack --progress --config webpack.config.js --mode production", "core:bundle:esm": "webpack --progress --config webpack.config.js --mode production --env output=esm", "core:watch": "npm run core:bundle -- --watch", - "lint": "npm run eslint && npm run eslint:spec", - "lint:fix": "npm run eslint -- --fix && npm run eslint:spec -- --fix", - "eslint": "eslint \"src/engine/**/*.ts\"", - "eslint:sandbox": "eslint \"sandbox/**/*.ts\"", - "eslint:spec": "eslint \"src/spec/**/*.ts\"", + "format": "prettier . --check", + "format:fix": "npm run format -- --write", + "lint": "npm run eslint", + "lint:fix": "npm run eslint -- --fix", + "eslint": "eslint .", "visual": "storybook dev", "build-storybook": "storybook build -o build-storybook", "sandbox:copy": "copyfiles -u 2 \"./build/dist/**/*.*\" \"./build/dist/*.*\" ./sandbox/lib/", @@ -59,7 +59,8 @@ "test:watch": "karma start --auto-watch --single-run=false", "coveralls": "echo 'Temporarily Remove Coveralls Due To Outage'", "apidocs": "node scripts/apidocs.js", - "release": "cross-env release=true npm run all" + "release": "cross-env release=true npm run all", + "prepare": "husky" }, "devDependencies": { "@babel/core": "7.24.3", @@ -89,6 +90,7 @@ "eslint-plugin-jsdoc": "48.2.2", "eslint-plugin-storybook": "0.8.0", "excalibur-jasmine": "0.3.4", + "husky": "9.0.11", "istanbul": "0.4.5", "istanbul-instrumenter-loader": "3.0.1", "jasmine": "5.1.0", @@ -103,6 +105,8 @@ "karma-spec-reporter": "0.0.36", "karma-summary-reporter": "3.1.1", "karma-webpack": "5.0.1", + "lint-staged": "15.2.2", + "prettier": "3.2.5", "puppeteer": "15.5.0", "raw-loader": "4.0.2", "react": "18.2.0", @@ -125,6 +129,10 @@ "dependencies": { "core-js": "3.36.1" }, + "lint-staged": { + "*.{js,jsx,ts,tsx,html,json,md,yml,yaml}": "prettier --write", + "*.{js,jsx,ts,tsx,html}": "eslint --fix" + }, "overrides": { "typedoc": { "typescript": ">=4.7.4" diff --git a/sandbox/excalibur-dev-tools/dev-tools.d.ts b/sandbox/excalibur-dev-tools/dev-tools.d.ts index bace632e..9fcd9b61 100644 --- a/sandbox/excalibur-dev-tools/dev-tools.d.ts +++ b/sandbox/excalibur-dev-tools/dev-tools.d.ts @@ -1,56 +1,56 @@ -import * as ex from "excalibur"; -import { BladeApi, FolderApi, Pane, TabApi, TabPageApi } from "tweakpane"; +import * as ex from 'excalibur'; +import { BladeApi, FolderApi, Pane, TabApi, TabPageApi } from 'tweakpane'; import { PickerSystem } from './picker-system'; export declare class DevTool { - engine: ex.Engine; - pane: Pane; - tabs: TabApi; - pickerSystem: PickerSystem; - pointerPos: { - x: number; - y: number; - }; - highlightedEntities: number[]; - selectedEntity: ex.Actor | null; - selectedEntityId: number; - currentResolution: ex.ScreenDimension; - currentViewport: ex.ScreenDimension; - resolutionText: BladeApi; - viewportText: BladeApi; - screenFolder: FolderApi; - selectedEntityTab: TabPageApi; - selectedEntityFolder: FolderApi; - screenTab: TabPageApi; - cameraTab: TabPageApi; - timerTab: TabPageApi; - clockTab: TabPageApi; - physicsTab: TabPageApi; - debugTab: TabPageApi; - pointerPosInput: any; - constructor(engine: ex.Engine); - /** - * Add any event listeners relevant to the devtool - */ - addListeners(): void; - selectEntityById(id: number): void; - /** - * `update()` is called periodically over time - * @param devtool - */ - update(devtool: DevTool): void; - private _installPickerSystemIfNeeded; - private _buildMain; - private _buildEntityUI; - private _buildColliderUI; - private _buildParticleEmitterUI; - private _buildGraphicsUI; - private _buildMotionUI; - private _buildTransformUI; - private _buildScreenTab; - private _buildCameraTab; - private _buildClockTab; - private _timersFolder; - private _buildTimersTab; - private _buildPhysicsTab; - private _buildDebugSettingsTab; + engine: ex.Engine; + pane: Pane; + tabs: TabApi; + pickerSystem: PickerSystem; + pointerPos: { + x: number; + y: number; + }; + highlightedEntities: number[]; + selectedEntity: ex.Actor | null; + selectedEntityId: number; + currentResolution: ex.ScreenDimension; + currentViewport: ex.ScreenDimension; + resolutionText: BladeApi; + viewportText: BladeApi; + screenFolder: FolderApi; + selectedEntityTab: TabPageApi; + selectedEntityFolder: FolderApi; + screenTab: TabPageApi; + cameraTab: TabPageApi; + timerTab: TabPageApi; + clockTab: TabPageApi; + physicsTab: TabPageApi; + debugTab: TabPageApi; + pointerPosInput: any; + constructor(engine: ex.Engine); + /** + * Add any event listeners relevant to the devtool + */ + addListeners(): void; + selectEntityById(id: number): void; + /** + * `update()` is called periodically over time + * @param devtool + */ + update(devtool: DevTool): void; + private _installPickerSystemIfNeeded; + private _buildMain; + private _buildEntityUI; + private _buildColliderUI; + private _buildParticleEmitterUI; + private _buildGraphicsUI; + private _buildMotionUI; + private _buildTransformUI; + private _buildScreenTab; + private _buildCameraTab; + private _buildClockTab; + private _timersFolder; + private _buildTimersTab; + private _buildPhysicsTab; + private _buildDebugSettingsTab; } diff --git a/sandbox/excalibur-dev-tools/dev-tools.js b/sandbox/excalibur-dev-tools/dev-tools.js index a5e9079d..920e172d 100644 --- a/sandbox/excalibur-dev-tools/dev-tools.js +++ b/sandbox/excalibur-dev-tools/dev-tools.js @@ -1,3 +1,5254 @@ /*! For license information please see dev-tools.js.LICENSE.txt */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("excalibur")):"function"==typeof define&&define.amd?define(["excalibur"],e):"object"==typeof exports?exports.ex=e(require("excalibur")):(t.ex=t.ex||{},t.ex.DevTools=e(t.ex))}(self,(function(t){return(()=>{var e={"./picker-system.ts":(t,e,n)=>{"use strict";n.r(e),n.d(e,{PickerSystem:()=>s});var i=n("excalibur");class s extends i.System{constructor(){super(...arguments),this.types=["ex.transform"],this.systemType=i.SystemType.Update,this.priority=99,this.lastFrameEntityToPointers=new Map,this.currentFrameEntityToPointers=new Map}initialize(t){this._engine=t.engine,this._receiver=this._engine.input.pointers}addPointerToEntity(t,e){if(!this.currentFrameEntityToPointers.has(t.id))return void this.currentFrameEntityToPointers.set(t.id,[e]);const n=this.currentFrameEntityToPointers.get(t.id);this.currentFrameEntityToPointers.set(t.id,n.concat(e))}_processPointerToEntity(t){var e;let n,s,o;for(const r of t)if(!(r instanceof i.Particle)){if(n=r.get(i.TransformComponent),s=r.get(i.ColliderComponent),s){const t=s.get();if(t)for(const[e,s]of this._receiver.currentFramePointerCoords.entries())t.contains(n.coordPlane===i.CoordPlane.World?s.worldPos:s.screenPos)&&this.addPointerToEntity(r,e)}if(o=r.get(i.GraphicsComponent),o){const t=o.localBounds.transform(n.getGlobalMatrix());for(const[e,s]of this._receiver.currentFramePointerCoords.entries())t.contains(n.coordPlane===i.CoordPlane.World?s.worldPos:s.screenPos)&&this.addPointerToEntity(r,e)}if(!(null===(e=null==o?void 0:o.current)||void 0===e?void 0:e.length)&&!(null==s?void 0:s.get())||r instanceof i.ParticleEmitter){const t=i.BoundingBox.fromDimension(100,100).transform(n.getGlobalMatrix());for(const[e,s]of this._receiver.currentFramePointerCoords.entries())t.contains(n.coordPlane===i.CoordPlane.World?s.worldPos:s.screenPos)&&this.addPointerToEntity(r,e)}}}update(t,e){this._processPointerToEntity(t),this.lastFrameEntityToPointers.clear(),this.lastFrameEntityToPointers=new Map(this.currentFrameEntityToPointers),this.currentFrameEntityToPointers.clear()}}},"./node_modules/tweakpane/dist/tweakpane.js":function(t,e){!function(t){"use strict";class e{constructor(t){this.controller_=t}get disabled(){return this.controller_.viewProps.get("disabled")}set disabled(t){this.controller_.viewProps.set("disabled",t)}get hidden(){return this.controller_.viewProps.get("hidden")}set hidden(t){this.controller_.viewProps.set("hidden",t)}dispose(){this.controller_.viewProps.set("disposed",!0)}}class n{constructor(t){this.target=t}}class i extends n{constructor(t,e,n,i){super(t),this.value=e,this.presetKey=n,this.last=null==i||i}}class s extends n{constructor(t,e,n){super(t),this.value=e,this.presetKey=n}}class o extends n{constructor(t,e){super(t),this.expanded=e}}function r(t){return null==t}function a(t,e){if(t.length!==e.length)return!1;for(let n=0;n"View has been already disposed",invalidparams:t=>`Invalid parameters for '${t.name}'`,nomatchingcontroller:t=>`No matching controller for '${t.key}'`,nomatchingview:t=>`No matching view for '${JSON.stringify(t.params)}'`,notbindable:()=>"Value is not bindable",propertynotfound:t=>`Property '${t.name}' not found`,shouldneverhappen:()=>"This error should never happen"};class p{constructor(t){var e;this.message=null!==(e=l[t.type](t.context))&&void 0!==e?e:"Unexpected error",this.name=this.constructor.name,this.stack=new Error(this.message).stack,this.type=t.type}static alreadyDisposed(){return new p({type:"alreadydisposed"})}static notBindable(){return new p({type:"notbindable"})}static propertyNotFound(t){return new p({type:"propertynotfound",context:{name:t}})}static shouldNeverHappen(){return new p({type:"shouldneverhappen"})}}class d{constructor(t,e,n){this.obj_=t,this.key_=e,this.presetKey_=null!=n?n:e}static isBindable(t){return null!==t&&"object"==typeof t}get key(){return this.key_}get presetKey(){return this.presetKey_}read(){return this.obj_[this.key_]}write(t){this.obj_[this.key_]=t}writeProperty(t,e){const n=this.read();if(!d.isBindable(n))throw p.notBindable();if(!(t in n))throw p.propertyNotFound(t);n[t]=e}}class c extends e{get label(){return this.controller_.props.get("label")}set label(t){this.controller_.props.set("label",t)}get title(){var t;return null!==(t=this.controller_.valueController.props.get("title"))&&void 0!==t?t:""}set title(t){this.controller_.valueController.props.set("title",t)}on(t,e){const i=e.bind(this);return this.controller_.valueController.emitter.on(t,(()=>{i(new n(this))})),this}}class h{constructor(){this.observers_={}}on(t,e){let n=this.observers_[t];return n||(n=this.observers_[t]=[]),n.push({handler:e}),this}off(t,e){const n=this.observers_[t];return n&&(this.observers_[t]=n.filter((t=>t.handler!==e))),this}emit(t,e){const n=this.observers_[t];n&&n.forEach((t=>{t.handler(e)}))}}const u="tp";function v(t){return(e,n)=>[u,"-",t,"v",e?`_${e}`:"",n?`-${n}`:""].join("")}function m(t){return t.rawValue}function b(t,e){var n,i;t.emitter.on("change",(n=m,i=e,t=>i(n(t)))),e(t.rawValue)}function g(t,e,n){b(t.value(e),n)}function _(t,e){return n=>{!function(t,e,n){n?t.classList.add(e):t.classList.remove(e)}(t,e,n)}}function f(t,e){b(t,(t=>{e.textContent=null!=t?t:""}))}const w=v("btn");class x{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(w()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("button");n.classList.add(w("b")),e.viewProps.bindDisabled(n),this.element.appendChild(n),this.buttonElement=n;const i=t.createElement("div");i.classList.add(w("t")),f(e.props.value("title"),i),this.buttonElement.appendChild(i)}}class y{constructor(t,e){this.emitter=new h,this.onClick_=this.onClick_.bind(this),this.props=e.props,this.viewProps=e.viewProps,this.view=new x(t,{props:this.props,viewProps:this.viewProps}),this.view.buttonElement.addEventListener("click",this.onClick_)}onClick_(){this.emitter.emit("click",{sender:this})}}class C{constructor(t,e){var n;this.constraint_=null==e?void 0:e.constraint,this.equals_=null!==(n=null==e?void 0:e.equals)&&void 0!==n?n:(t,e)=>t===e,this.emitter=new h,this.rawValue_=t}get constraint(){return this.constraint_}get rawValue(){return this.rawValue_}set rawValue(t){this.setRawValue(t,{forceEmit:!1,last:!0})}setRawValue(t,e){const n=null!=e?e:{forceEmit:!1,last:!0},i=this.constraint_?this.constraint_.constrain(t):t;(!this.equals_(this.rawValue_,i)||n.forceEmit)&&(this.emitter.emit("beforechange",{sender:this}),this.rawValue_=i,this.emitter.emit("change",{options:n,rawValue:i,sender:this}))}}class P{constructor(t){this.emitter=new h,this.value_=t}get rawValue(){return this.value_}set rawValue(t){this.setRawValue(t,{forceEmit:!1,last:!0})}setRawValue(t,e){const n=null!=e?e:{forceEmit:!1,last:!0};(this.value_!==t||n.forceEmit)&&(this.emitter.emit("beforechange",{sender:this}),this.value_=t,this.emitter.emit("change",{options:n,rawValue:this.value_,sender:this}))}}function E(t,e){const n=null==e?void 0:e.constraint,i=null==e?void 0:e.equals;return n||i?new C(t,e):new P(t)}class k{constructor(t){this.emitter=new h,this.valMap_=t;for(const t in this.valMap_)this.valMap_[t].emitter.on("change",(()=>{this.emitter.emit("change",{key:t,sender:this})}))}static createCore(t){return Object.keys(t).reduce(((e,n)=>Object.assign(e,{[n]:E(t[n])})),{})}static fromObject(t){const e=this.createCore(t);return new k(e)}get(t){return this.valMap_[t].rawValue}set(t,e){this.valMap_[t].rawValue=e}value(t){return this.valMap_[t]}}function V(t){return e=>n=>{if(!e&&void 0===n)return{succeeded:!1,value:void 0};if(e&&void 0===n)return{succeeded:!0,value:void 0};const i=t(n);return void 0!==i?{succeeded:!0,value:i}:{succeeded:!1,value:void 0}}}function S(t){return{custom:e=>V(e)(t),boolean:V((t=>"boolean"==typeof t?t:void 0))(t),number:V((t=>"number"==typeof t?t:void 0))(t),string:V((t=>"string"==typeof t?t:void 0))(t),function:V((t=>"function"==typeof t?t:void 0))(t),constant:e=>V((t=>t===e?e:void 0))(t),raw:V((t=>t))(t),object:e=>V((t=>{if(null!==(n=t)&&"object"==typeof n)return function(t,e){return Object.keys(e).reduce(((n,i)=>{if(void 0===n)return;const s=(0,e[i])(t[i]);return s.succeeded?Object.assign(Object.assign({},n),{[i]:s.value}):void 0}),{})}(t,e);var n}))(t),array:e=>V((t=>{if(Array.isArray(t))return n=e,t.reduce(((t,e)=>{if(void 0===t)return;const i=n(e);return i.succeeded&&void 0!==i.value?[...t,i.value]:void 0}),[]);var n}))(t)}}const M={optional:S(!0),required:S(!1)};function L(t,e){const n=M.required.object(e)(t);return n.succeeded?n.value:void 0}const A=v(""),I={veryfirst:"vfst",first:"fst",last:"lst",verylast:"vlst"};class T{constructor(t){this.parent_=null,this.blade=t.blade,this.view=t.view,this.viewProps=t.viewProps;const e=this.view.element;this.blade.value("positions").emitter.on("change",(()=>{["veryfirst","first","last","verylast"].forEach((t=>{e.classList.remove(A(void 0,I[t]))})),this.blade.get("positions").forEach((t=>{e.classList.add(A(void 0,I[t]))}))})),this.viewProps.handleDispose((()=>{!function(t){t&&t.parentElement&&t.parentElement.removeChild(t)}(e)}))}get parent(){return this.parent_}}const D="http://www.w3.org/2000/svg";function j(t){t.offsetHeight}function B(t){return void 0!==t.ontouchstart}function R(){return new Function("return this")().document}const F={check:'',dropdown:'',p2dpad:''};function U(t,e){const n=t.createElementNS(D,"svg");return n.innerHTML=F[e],n}function O(t,e,n){t.insertBefore(e,t.children[n])}function K(t){t.parentElement&&t.parentElement.removeChild(t)}function N(t){for(;t.children.length>0;)t.removeChild(t.children[0])}function $(t){return t.relatedTarget?t.relatedTarget:"explicitOriginalTarget"in t?t.explicitOriginalTarget:null}const z=v("lbl");class H{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(z()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("div");n.classList.add(z("l")),g(e.props,"label",(e=>{r(e)?this.element.classList.add(z(void 0,"nol")):(this.element.classList.remove(z(void 0,"nol")),function(t){for(;t.childNodes.length>0;)t.removeChild(t.childNodes[0])}(n),n.appendChild(function(t,e){const n=t.createDocumentFragment();return e.split("\n").map((e=>t.createTextNode(e))).forEach(((e,i)=>{i>0&&n.appendChild(t.createElement("br")),n.appendChild(e)})),n}(t,e)))})),this.element.appendChild(n),this.labelElement=n;const i=t.createElement("div");i.classList.add(z("v")),this.element.appendChild(i),this.valueElement=i}}class q extends T{constructor(t,e){const n=e.valueController.viewProps;super(Object.assign(Object.assign({},e),{view:new H(t,{props:e.props,viewProps:n}),viewProps:n})),this.props=e.props,this.valueController=e.valueController,this.view.valueElement.appendChild(this.valueController.view.element)}}const G={id:"button",type:"blade",accept(t){const e=M,n=L(t,{title:e.required.string,view:e.required.constant("button"),label:e.optional.string});return n?{params:n}:null},controller:t=>new q(t.document,{blade:t.blade,props:k.fromObject({label:t.params.label}),valueController:new y(t.document,{props:k.fromObject({title:t.params.title}),viewProps:t.viewProps})}),api:t=>t.controller instanceof q&&t.controller.valueController instanceof y?new c(t.controller):null};class Y extends T{constructor(t){super(t),this.value=t.value}}function W(){return new k({positions:E([],{equals:a})})}class X extends k{constructor(t){super(t)}static create(t){const e={completed:!0,expanded:t,expandedHeight:null,shouldFixHeight:!1,temporaryExpanded:null},n=k.createCore(e);return new X(n)}get styleExpanded(){var t;return null!==(t=this.get("temporaryExpanded"))&&void 0!==t?t:this.get("expanded")}get styleHeight(){if(!this.styleExpanded)return"0";const t=this.get("expandedHeight");return this.get("shouldFixHeight")&&!r(t)?`${t}px`:"auto"}bindExpandedClass(t,e){g(this,"expanded",(()=>{this.styleExpanded?t.classList.add(e):t.classList.remove(e)}))}}function Q(t,e){e.style.height=t.styleHeight}function J(t,e){t.value("expanded").emitter.on("beforechange",(()=>{t.set("completed",!1),r(t.get("expandedHeight"))&&t.set("expandedHeight",function(t,e){let n=0;return function(t,e){const n=t.style.transition;t.style.transition="none",e(),t.style.transition=n}(e,(()=>{t.set("expandedHeight",null),t.set("temporaryExpanded",!0),j(e),n=e.clientHeight,t.set("temporaryExpanded",null),j(e)})),n}(t,e)),t.set("shouldFixHeight",!0),j(e)})),t.emitter.on("change",(()=>{Q(t,e)})),Q(t,e),e.addEventListener("transitionend",(e=>{"height"===e.propertyName&&(t.set("shouldFixHeight",!1),t.set("expandedHeight",null),t.set("completed",!0))}))}class Z extends e{constructor(t,e){super(t),this.rackApi_=e}}class tt{constructor(t){this.emitter=new h,this.items_=[],this.cache_=new Set,this.onSubListAdd_=this.onSubListAdd_.bind(this),this.onSubListRemove_=this.onSubListRemove_.bind(this),this.extract_=t}get items(){return this.items_}allItems(){return Array.from(this.cache_)}find(t){for(const e of this.allItems())if(t(e))return e;return null}includes(t){return this.cache_.has(t)}add(t,e){if(this.includes(t))throw p.shouldNeverHappen();const n=void 0!==e?e:this.items_.length;this.items_.splice(n,0,t),this.cache_.add(t);const i=this.extract_(t);i&&(i.emitter.on("add",this.onSubListAdd_),i.emitter.on("remove",this.onSubListRemove_),i.allItems().forEach((t=>{this.cache_.add(t)}))),this.emitter.emit("add",{index:n,item:t,root:this,target:this})}remove(t){const e=this.items_.indexOf(t);if(e<0)return;this.items_.splice(e,1),this.cache_.delete(t);const n=this.extract_(t);n&&(n.emitter.off("add",this.onSubListAdd_),n.emitter.off("remove",this.onSubListRemove_)),this.emitter.emit("remove",{index:e,item:t,root:this,target:this})}onSubListAdd_(t){this.cache_.add(t.item),this.emitter.emit("add",{index:t.index,item:t.item,root:this,target:t.target})}onSubListRemove_(t){this.cache_.delete(t.item),this.emitter.emit("remove",{index:t.index,item:t.item,root:this,target:t.target})}}class et extends e{constructor(t){super(t),this.onBindingChange_=this.onBindingChange_.bind(this),this.emitter_=new h,this.controller_.binding.emitter.on("change",this.onBindingChange_)}get label(){return this.controller_.props.get("label")}set label(t){this.controller_.props.set("label",t)}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}refresh(){this.controller_.binding.read()}onBindingChange_(t){const e=t.sender.target.read();this.emitter_.emit("change",{event:new i(this,e,this.controller_.binding.target.presetKey,t.options.last)})}}class nt extends q{constructor(t,e){super(t,e),this.binding=e.binding}}class it extends e{constructor(t){super(t),this.onBindingUpdate_=this.onBindingUpdate_.bind(this),this.emitter_=new h,this.controller_.binding.emitter.on("update",this.onBindingUpdate_)}get label(){return this.controller_.props.get("label")}set label(t){this.controller_.props.set("label",t)}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}refresh(){this.controller_.binding.read()}onBindingUpdate_(t){const e=t.sender.target.read();this.emitter_.emit("update",{event:new s(this,e,this.controller_.binding.target.presetKey)})}}class st extends q{constructor(t,e){super(t,e),this.binding=e.binding,this.viewProps.bindDisabled(this.binding.ticker),this.viewProps.handleDispose((()=>{this.binding.dispose()}))}}function ot(t){return t instanceof lt?t.apiSet_:t instanceof Z?t.rackApi_.apiSet_:null}function rt(t,e){const n=t.find((t=>t.controller_===e));if(!n)throw p.shouldNeverHappen();return n}function at(t,e,n){if(!d.isBindable(t))throw p.notBindable();return new d(t,e,n)}class lt extends e{constructor(t,e){super(t),this.onRackAdd_=this.onRackAdd_.bind(this),this.onRackRemove_=this.onRackRemove_.bind(this),this.onRackInputChange_=this.onRackInputChange_.bind(this),this.onRackMonitorUpdate_=this.onRackMonitorUpdate_.bind(this),this.emitter_=new h,this.apiSet_=new tt(ot),this.pool_=e;const n=this.controller_.rack;n.emitter.on("add",this.onRackAdd_),n.emitter.on("remove",this.onRackRemove_),n.emitter.on("inputchange",this.onRackInputChange_),n.emitter.on("monitorupdate",this.onRackMonitorUpdate_),n.children.forEach((t=>{this.setUpApi_(t)}))}get children(){return this.controller_.rack.children.map((t=>rt(this.apiSet_,t)))}addInput(t,e,n){const i=n||{},s=this.controller_.view.element.ownerDocument,o=this.pool_.createInput(s,at(t,e,i.presetKey),i),r=new et(o);return this.add(r,i.index)}addMonitor(t,e,n){const i=n||{},s=this.controller_.view.element.ownerDocument,o=this.pool_.createMonitor(s,at(t,e),i),r=new it(o);return this.add(r,i.index)}addFolder(t){return function(t,e){return t.addBlade(Object.assign(Object.assign({},e),{view:"folder"}))}(this,t)}addButton(t){return function(t,e){return t.addBlade(Object.assign(Object.assign({},e),{view:"button"}))}(this,t)}addSeparator(t){return function(t,e){const n=e||{};return t.addBlade(Object.assign(Object.assign({},n),{view:"separator"}))}(this,t)}addTab(t){return function(t,e){return t.addBlade(Object.assign(Object.assign({},e),{view:"tab"}))}(this,t)}add(t,e){this.controller_.rack.add(t.controller_,e);const n=this.apiSet_.find((e=>e.controller_===t.controller_));return n&&this.apiSet_.remove(n),this.apiSet_.add(t),t}remove(t){this.controller_.rack.remove(t.controller_)}addBlade(t){const e=this.controller_.view.element.ownerDocument,n=this.pool_.createBlade(e,t),i=this.pool_.createBladeApi(n);return this.add(i,t.index)}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}setUpApi_(t){this.apiSet_.find((e=>e.controller_===t))||this.apiSet_.add(this.pool_.createBladeApi(t))}onRackAdd_(t){this.setUpApi_(t.bladeController)}onRackRemove_(t){if(t.isRoot){const e=rt(this.apiSet_,t.bladeController);this.apiSet_.remove(e)}}onRackInputChange_(t){const e=t.bladeController;if(e instanceof nt){const n=rt(this.apiSet_,e),s=e.binding;this.emitter_.emit("change",{event:new i(n,s.target.read(),s.target.presetKey,t.options.last)})}else if(e instanceof Y){const n=rt(this.apiSet_,e);this.emitter_.emit("change",{event:new i(n,e.value.rawValue,void 0,t.options.last)})}}onRackMonitorUpdate_(t){if(!(t.bladeController instanceof st))throw p.shouldNeverHappen();const e=rt(this.apiSet_,t.bladeController),n=t.bladeController.binding;this.emitter_.emit("update",{event:new s(e,n.target.read(),n.target.presetKey)})}}class pt extends Z{constructor(t,e){super(t,new lt(t.rackController,e)),this.emitter_=new h,this.controller_.foldable.value("expanded").emitter.on("change",(t=>{this.emitter_.emit("fold",{event:new o(this,t.sender.rawValue)})})),this.rackApi_.on("change",(t=>{this.emitter_.emit("change",{event:t})})),this.rackApi_.on("update",(t=>{this.emitter_.emit("update",{event:t})}))}get expanded(){return this.controller_.foldable.get("expanded")}set expanded(t){this.controller_.foldable.set("expanded",t)}get title(){return this.controller_.props.get("title")}set title(t){this.controller_.props.set("title",t)}get children(){return this.rackApi_.children}addInput(t,e,n){return this.rackApi_.addInput(t,e,n)}addMonitor(t,e,n){return this.rackApi_.addMonitor(t,e,n)}addFolder(t){return this.rackApi_.addFolder(t)}addButton(t){return this.rackApi_.addButton(t)}addSeparator(t){return this.rackApi_.addSeparator(t)}addTab(t){return this.rackApi_.addTab(t)}add(t,e){return this.rackApi_.add(t,e)}remove(t){this.rackApi_.remove(t)}addBlade(t){return this.rackApi_.addBlade(t)}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}}class dt extends T{constructor(t){super({blade:t.blade,view:t.view,viewProps:t.rackController.viewProps}),this.rackController=t.rackController}}class ct{constructor(t,e){const n=v(e.viewName);this.element=t.createElement("div"),this.element.classList.add(n()),e.viewProps.bindClassModifiers(this.element)}}function ht(t){return t instanceof mt?t.rack:t instanceof dt?t.rackController.rack:null}function ut(t){const e=ht(t);return e?e.bcSet_:null}class vt{constructor(t){var e;this.onBladePositionsChange_=this.onBladePositionsChange_.bind(this),this.onSetAdd_=this.onSetAdd_.bind(this),this.onSetRemove_=this.onSetRemove_.bind(this),this.onChildDispose_=this.onChildDispose_.bind(this),this.onChildPositionsChange_=this.onChildPositionsChange_.bind(this),this.onChildInputChange_=this.onChildInputChange_.bind(this),this.onChildMonitorUpdate_=this.onChildMonitorUpdate_.bind(this),this.onChildValueChange_=this.onChildValueChange_.bind(this),this.onChildViewPropsChange_=this.onChildViewPropsChange_.bind(this),this.onDescendantLayout_=this.onDescendantLayout_.bind(this),this.onDescendantInputChange_=this.onDescendantInputChange_.bind(this),this.onDescendantMonitorUpdate_=this.onDescendantMonitorUpdate_.bind(this),this.emitter=new h,this.blade_=null!=t?t:null,null===(e=this.blade_)||void 0===e||e.value("positions").emitter.on("change",this.onBladePositionsChange_),this.bcSet_=new tt(ut),this.bcSet_.emitter.on("add",this.onSetAdd_),this.bcSet_.emitter.on("remove",this.onSetRemove_)}get children(){return this.bcSet_.items}add(t,e){t.parent&&t.parent.remove(t),t.parent_=this,this.bcSet_.add(t,e)}remove(t){t.parent_=null,this.bcSet_.remove(t)}find(t){return this.bcSet_.allItems().filter((e=>e instanceof t))}onSetAdd_(t){this.updatePositions_();const e=t.target===t.root;if(this.emitter.emit("add",{bladeController:t.item,index:t.index,isRoot:e,sender:this}),!e)return;const n=t.item;if(n.viewProps.emitter.on("change",this.onChildViewPropsChange_),n.blade.value("positions").emitter.on("change",this.onChildPositionsChange_),n.viewProps.handleDispose(this.onChildDispose_),n instanceof nt)n.binding.emitter.on("change",this.onChildInputChange_);else if(n instanceof st)n.binding.emitter.on("update",this.onChildMonitorUpdate_);else if(n instanceof Y)n.value.emitter.on("change",this.onChildValueChange_);else{const t=ht(n);if(t){const e=t.emitter;e.on("layout",this.onDescendantLayout_),e.on("inputchange",this.onDescendantInputChange_),e.on("monitorupdate",this.onDescendantMonitorUpdate_)}}}onSetRemove_(t){this.updatePositions_();const e=t.target===t.root;if(this.emitter.emit("remove",{bladeController:t.item,isRoot:e,sender:this}),!e)return;const n=t.item;if(n instanceof nt)n.binding.emitter.off("change",this.onChildInputChange_);else if(n instanceof st)n.binding.emitter.off("update",this.onChildMonitorUpdate_);else if(n instanceof Y)n.value.emitter.off("change",this.onChildValueChange_);else{const t=ht(n);if(t){const e=t.emitter;e.off("layout",this.onDescendantLayout_),e.off("inputchange",this.onDescendantInputChange_),e.off("monitorupdate",this.onDescendantMonitorUpdate_)}}}updatePositions_(){const t=this.bcSet_.items.filter((t=>!t.viewProps.get("hidden"))),e=t[0],n=t[t.length-1];this.bcSet_.items.forEach((t=>{const i=[];t===e&&(i.push("first"),this.blade_&&!this.blade_.get("positions").includes("veryfirst")||i.push("veryfirst")),t===n&&(i.push("last"),this.blade_&&!this.blade_.get("positions").includes("verylast")||i.push("verylast")),t.blade.set("positions",i)}))}onChildPositionsChange_(){this.updatePositions_(),this.emitter.emit("layout",{sender:this})}onChildViewPropsChange_(t){this.updatePositions_(),this.emitter.emit("layout",{sender:this})}onChildDispose_(){this.bcSet_.items.filter((t=>t.viewProps.get("disposed"))).forEach((t=>{this.bcSet_.remove(t)}))}onChildInputChange_(t){const e=function(t,e){for(let n=0;n{for(let t=this.rack.children.length-1;t>=0;t--)this.rack.children[t].viewProps.set("disposed",!0)}))}onRackAdd_(t){t.isRoot&&O(this.view.element,t.bladeController.view.element,t.index)}onRackRemove_(t){t.isRoot&&K(t.bladeController.view.element)}}const bt=v("cnt");class gt{constructor(t,e){this.className_=v(e.viewName||"fld"),this.element=t.createElement("div"),this.element.classList.add(this.className_(),bt()),e.viewProps.bindClassModifiers(this.element),this.foldable_=e.foldable,this.foldable_.bindExpandedClass(this.element,this.className_(void 0,"expanded")),g(this.foldable_,"completed",_(this.element,this.className_(void 0,"cpl")));const n=t.createElement("button");n.classList.add(this.className_("b")),g(e.props,"title",(t=>{r(t)?this.element.classList.add(this.className_(void 0,"not")):this.element.classList.remove(this.className_(void 0,"not"))})),e.viewProps.bindDisabled(n),this.element.appendChild(n),this.buttonElement=n;const i=t.createElement("div");i.classList.add(this.className_("t")),f(e.props.value("title"),i),this.buttonElement.appendChild(i),this.titleElement=i;const s=t.createElement("div");s.classList.add(this.className_("m")),this.buttonElement.appendChild(s);const o=e.containerElement;o.classList.add(this.className_("c")),this.element.appendChild(o),this.containerElement=o}}class _t extends dt{constructor(t,e){var n;const i=X.create(null===(n=e.expanded)||void 0===n||n),s=new mt(t,{blade:e.blade,root:e.root,viewProps:e.viewProps});super(Object.assign(Object.assign({},e),{rackController:s,view:new gt(t,{containerElement:s.view.element,foldable:i,props:e.props,viewName:e.root?"rot":void 0,viewProps:e.viewProps})})),this.onTitleClick_=this.onTitleClick_.bind(this),this.props=e.props,this.foldable=i,J(this.foldable,this.view.containerElement),this.view.buttonElement.addEventListener("click",this.onTitleClick_)}get document(){return this.view.element.ownerDocument}onTitleClick_(){this.foldable.set("expanded",!this.foldable.get("expanded"))}}const ft={id:"folder",type:"blade",accept(t){const e=M,n=L(t,{title:e.required.string,view:e.required.constant("folder"),expanded:e.optional.boolean});return n?{params:n}:null},controller:t=>new _t(t.document,{blade:t.blade,expanded:t.params.expanded,props:k.fromObject({title:t.params.title}),viewProps:t.viewProps}),api:t=>t.controller instanceof _t?new pt(t.controller,t.pool):null};class wt extends Y{constructor(t,e){const n=e.valueController.viewProps;super(Object.assign(Object.assign({},e),{value:e.valueController.value,view:new H(t,{props:e.props,viewProps:n}),viewProps:n})),this.props=e.props,this.valueController=e.valueController,this.view.valueElement.appendChild(this.valueController.view.element)}}class xt extends e{}const yt=v("spr");class Ct{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(yt()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("hr");n.classList.add(yt("r")),this.element.appendChild(n)}}class Pt extends T{constructor(t,e){super(Object.assign(Object.assign({},e),{view:new Ct(t,{viewProps:e.viewProps})}))}}const Et={id:"separator",type:"blade",accept(t){const e=L(t,{view:M.required.constant("separator")});return e?{params:e}:null},controller:t=>new Pt(t.document,{blade:t.blade,viewProps:t.viewProps}),api:t=>t.controller instanceof Pt?new xt(t.controller):null},kt=v("");function Vt(t,e){return _(t,kt(void 0,e))}class St extends k{constructor(t){super(t)}static create(t){var e,n;const i=null!=t?t:{},s={disabled:null!==(e=i.disabled)&&void 0!==e&&e,disposed:!1,hidden:null!==(n=i.hidden)&&void 0!==n&&n},o=k.createCore(s);return new St(o)}bindClassModifiers(t){g(this,"disabled",Vt(t,"disabled")),g(this,"hidden",Vt(t,"hidden"))}bindDisabled(t){g(this,"disabled",(e=>{t.disabled=e}))}bindTabIndex(t){g(this,"disabled",(e=>{t.tabIndex=e?-1:0}))}handleDispose(t){this.value("disposed").emitter.on("change",(e=>{e&&t()}))}}const Mt=v("tbi");class Lt{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(Mt()),e.viewProps.bindClassModifiers(this.element),g(e.props,"selected",(t=>{t?this.element.classList.add(Mt(void 0,"sel")):this.element.classList.remove(Mt(void 0,"sel"))}));const n=t.createElement("button");n.classList.add(Mt("b")),e.viewProps.bindDisabled(n),this.element.appendChild(n),this.buttonElement=n;const i=t.createElement("div");i.classList.add(Mt("t")),f(e.props.value("title"),i),this.buttonElement.appendChild(i),this.titleElement=i}}class At{constructor(t,e){this.emitter=new h,this.onClick_=this.onClick_.bind(this),this.props=e.props,this.viewProps=e.viewProps,this.view=new Lt(t,{props:e.props,viewProps:e.viewProps}),this.view.buttonElement.addEventListener("click",this.onClick_)}onClick_(){this.emitter.emit("click",{sender:this})}}class It{constructor(t,e){this.onItemClick_=this.onItemClick_.bind(this),this.ic_=new At(t,{props:e.itemProps,viewProps:St.create()}),this.ic_.emitter.on("click",this.onItemClick_),this.cc_=new mt(t,{blade:W(),viewProps:St.create()}),this.props=e.props,g(this.props,"selected",(t=>{this.itemController.props.set("selected",t),this.contentController.viewProps.set("hidden",!t)}))}get itemController(){return this.ic_}get contentController(){return this.cc_}onItemClick_(){this.props.set("selected",!0)}}class Tt{constructor(t,e){this.controller_=t,this.rackApi_=e}get title(){var t;return null!==(t=this.controller_.itemController.props.get("title"))&&void 0!==t?t:""}set title(t){this.controller_.itemController.props.set("title",t)}get selected(){return this.controller_.props.get("selected")}set selected(t){this.controller_.props.set("selected",t)}get children(){return this.rackApi_.children}addButton(t){return this.rackApi_.addButton(t)}addFolder(t){return this.rackApi_.addFolder(t)}addSeparator(t){return this.rackApi_.addSeparator(t)}addTab(t){return this.rackApi_.addTab(t)}add(t,e){this.rackApi_.add(t,e)}remove(t){this.rackApi_.remove(t)}addInput(t,e,n){return this.rackApi_.addInput(t,e,n)}addMonitor(t,e,n){return this.rackApi_.addMonitor(t,e,n)}addBlade(t){return this.rackApi_.addBlade(t)}}class Dt extends Z{constructor(t,e){super(t,new lt(t.rackController,e)),this.onPageAdd_=this.onPageAdd_.bind(this),this.onPageRemove_=this.onPageRemove_.bind(this),this.emitter_=new h,this.pageApiMap_=new Map,this.rackApi_.on("change",(t=>{this.emitter_.emit("change",{event:t})})),this.rackApi_.on("update",(t=>{this.emitter_.emit("update",{event:t})})),this.controller_.pageSet.emitter.on("add",this.onPageAdd_),this.controller_.pageSet.emitter.on("remove",this.onPageRemove_),this.controller_.pageSet.items.forEach((t=>{this.setUpPageApi_(t)}))}get pages(){return this.controller_.pageSet.items.map((t=>{const e=this.pageApiMap_.get(t);if(!e)throw p.shouldNeverHappen();return e}))}addPage(t){const e=this.controller_.view.element.ownerDocument,n=new It(e,{itemProps:k.fromObject({selected:!1,title:t.title}),props:k.fromObject({selected:!1})});this.controller_.add(n,t.index);const i=this.pageApiMap_.get(n);if(!i)throw p.shouldNeverHappen();return i}removePage(t){this.controller_.remove(t)}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}setUpPageApi_(t){const e=this.rackApi_.apiSet_.find((e=>e.controller_===t.contentController));if(!e)throw p.shouldNeverHappen();const n=new Tt(t,e);this.pageApiMap_.set(t,n)}onPageAdd_(t){this.setUpPageApi_(t.item)}onPageRemove_(t){if(!this.pageApiMap_.get(t.item))throw p.shouldNeverHappen();this.pageApiMap_.delete(t.item)}}const jt=v("tab");class Bt{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(jt(),bt()),e.viewProps.bindClassModifiers(this.element),b(e.empty,_(this.element,jt(void 0,"nop")));const n=t.createElement("div");n.classList.add(jt("i")),this.element.appendChild(n),this.itemsElement=n;const i=e.contentsElement;i.classList.add(jt("c")),this.element.appendChild(i),this.contentsElement=i}}class Rt extends dt{constructor(t,e){const n=new mt(t,{blade:e.blade,viewProps:e.viewProps}),i=E(!0);super({blade:e.blade,rackController:n,view:new Bt(t,{contentsElement:n.view.element,empty:i,viewProps:e.viewProps})}),this.onPageAdd_=this.onPageAdd_.bind(this),this.onPageRemove_=this.onPageRemove_.bind(this),this.onPageSelectedChange_=this.onPageSelectedChange_.bind(this),this.pageSet_=new tt((()=>null)),this.pageSet_.emitter.on("add",this.onPageAdd_),this.pageSet_.emitter.on("remove",this.onPageRemove_),this.empty_=i,this.applyPages_()}get pageSet(){return this.pageSet_}add(t,e){this.pageSet_.add(t,null!=e?e:this.pageSet_.items.length)}remove(t){this.pageSet_.remove(this.pageSet_.items[t])}applyPages_(){this.keepSelection_(),this.empty_.rawValue=0===this.pageSet_.items.length}onPageAdd_(t){const e=t.item;O(this.view.itemsElement,e.itemController.view.element,t.index),this.rackController.rack.add(e.contentController,t.index),e.props.value("selected").emitter.on("change",this.onPageSelectedChange_),this.applyPages_()}onPageRemove_(t){const e=t.item;K(e.itemController.view.element),this.rackController.rack.remove(e.contentController),e.props.value("selected").emitter.off("change",this.onPageSelectedChange_),this.applyPages_()}keepSelection_(){if(0===this.pageSet_.items.length)return;const t=this.pageSet_.items.findIndex((t=>t.props.get("selected")));t<0?this.pageSet_.items.forEach(((t,e)=>{t.props.set("selected",0===e)})):this.pageSet_.items.forEach(((e,n)=>{e.props.set("selected",n===t)}))}onPageSelectedChange_(t){if(t.rawValue){const e=this.pageSet_.items.findIndex((e=>e.props.value("selected")===t.sender));this.pageSet_.items.forEach(((t,n)=>{t.props.set("selected",n===e)}))}else this.keepSelection_()}}const Ft={id:"tab",type:"blade",accept(t){const e=M,n=L(t,{pages:e.required.array(e.required.object({title:e.required.string})),view:e.required.constant("tab")});return n&&0!==n.pages.length?{params:n}:null},controller(t){const e=new Rt(t.document,{blade:t.blade,viewProps:t.viewProps});return t.params.pages.forEach((n=>{const i=new It(t.document,{itemProps:k.fromObject({selected:!1,title:n.title}),props:k.fromObject({selected:!1})});e.add(i)})),e},api:t=>t.controller instanceof Rt?new Dt(t.controller,t.pool):null};class Ut{constructor(){this.disabled=!1,this.emitter=new h}dispose(){}tick(){this.disabled||this.emitter.emit("tick",{sender:this})}}class Ot{constructor(t,e){this.disabled_=!1,this.timerId_=null,this.onTick_=this.onTick_.bind(this),this.doc_=t,this.emitter=new h,this.interval_=e,this.setTimer_()}get disabled(){return this.disabled_}set disabled(t){this.disabled_=t,this.disabled_?this.clearTimer_():this.setTimer_()}dispose(){this.clearTimer_()}clearTimer_(){if(null===this.timerId_)return;const t=this.doc_.defaultView;t&&t.clearInterval(this.timerId_),this.timerId_=null}setTimer_(){if(this.clearTimer_(),this.interval_<=0)return;const t=this.doc_.defaultView;t&&(this.timerId_=t.setInterval(this.onTick_,this.interval_))}onTick_(){this.disabled_||this.emitter.emit("tick",{sender:this})}}class Kt{constructor(t){this.constraints=t}constrain(t){return this.constraints.reduce(((t,e)=>e.constrain(t)),t)}}function Nt(t,e){if(t instanceof e)return t;if(t instanceof Kt){const n=t.constraints.reduce(((t,n)=>t||(n instanceof e?n:null)),null);if(n)return n}return null}class $t{constructor(t){this.options=t}constrain(t){const e=this.options;return 0===e.length||e.filter((e=>e.value===t)).length>0?t:e[0].value}}class zt{constructor(t){this.maxValue=t.max,this.minValue=t.min}constrain(t){let e=t;return r(this.minValue)||(e=Math.max(e,this.minValue)),r(this.maxValue)||(e=Math.min(e,this.maxValue)),e}}class Ht{constructor(t){this.step=t}constrain(t){return(t<0?-Math.round(-t/this.step):Math.round(t/this.step))*this.step}}const qt=v("lst");class Gt{constructor(t,e){this.onValueChange_=this.onValueChange_.bind(this),this.props_=e.props,this.element=t.createElement("div"),this.element.classList.add(qt()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("select");n.classList.add(qt("s")),g(this.props_,"options",(e=>{N(n),e.forEach(((e,i)=>{const s=t.createElement("option");s.dataset.index=String(i),s.textContent=e.text,s.value=String(e.value),n.appendChild(s)}))})),e.viewProps.bindDisabled(n),this.element.appendChild(n),this.selectElement=n;const i=t.createElement("div");i.classList.add(qt("m")),i.appendChild(U(t,"dropdown")),this.element.appendChild(i),e.value.emitter.on("change",this.onValueChange_),this.value_=e.value,this.update_()}update_(){this.selectElement.value=String(this.value_.rawValue)}onValueChange_(){this.update_()}}class Yt{constructor(t,e){this.onSelectChange_=this.onSelectChange_.bind(this),this.props=e.props,this.value=e.value,this.viewProps=e.viewProps,this.view=new Gt(t,{props:this.props,value:this.value,viewProps:this.viewProps}),this.view.selectElement.addEventListener("change",this.onSelectChange_)}onSelectChange_(t){const e=t.currentTarget.selectedOptions.item(0);if(!e)return;const n=Number(e.dataset.index);this.value.rawValue=this.props.get("options")[n].value}}const Wt=v("pop");class Xt{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(Wt()),e.viewProps.bindClassModifiers(this.element),b(e.shows,_(this.element,Wt(void 0,"v")))}}class Qt{constructor(t,e){this.shows=E(!1),this.viewProps=e.viewProps,this.view=new Xt(t,{shows:this.shows,viewProps:this.viewProps})}}const Jt=v("txt");class Zt{constructor(t,e){this.onChange_=this.onChange_.bind(this),this.element=t.createElement("div"),this.element.classList.add(Jt()),e.viewProps.bindClassModifiers(this.element),this.props_=e.props,this.props_.emitter.on("change",this.onChange_);const n=t.createElement("input");n.classList.add(Jt("i")),n.type="text",e.viewProps.bindDisabled(n),this.element.appendChild(n),this.inputElement=n,e.value.emitter.on("change",this.onChange_),this.value_=e.value,this.refresh()}refresh(){const t=this.props_.get("formatter");this.inputElement.value=t(this.value_.rawValue)}onChange_(){this.refresh()}}class te{constructor(t,e){this.onInputChange_=this.onInputChange_.bind(this),this.parser_=e.parser,this.props=e.props,this.value=e.value,this.viewProps=e.viewProps,this.view=new Zt(t,{props:e.props,value:this.value,viewProps:this.viewProps}),this.view.inputElement.addEventListener("change",this.onInputChange_)}onInputChange_(t){const e=t.currentTarget.value,n=this.parser_(e);r(n)||(this.value.rawValue=n),this.view.refresh()}}function ee(t){return"false"!==t&&!!t}function ne(t){return function(t){return String(t)}(t)}class ie{constructor(t){this.text=t}evaluate(){return Number(this.text)}toString(){return this.text}}const se={"**":(t,e)=>Math.pow(t,e),"*":(t,e)=>t*e,"/":(t,e)=>t/e,"%":(t,e)=>t%e,"+":(t,e)=>t+e,"-":(t,e)=>t-e,"<<":(t,e)=>t<>":(t,e)=>t>>e,">>>":(t,e)=>t>>>e,"&":(t,e)=>t&e,"^":(t,e)=>t^e,"|":(t,e)=>t|e};class oe{constructor(t,e,n){this.left=e,this.operator=t,this.right=n}evaluate(){const t=se[this.operator];if(!t)throw new Error(`unexpected binary operator: '${this.operator}`);return t(this.left.evaluate(),this.right.evaluate())}toString(){return["b(",this.left.toString(),this.operator,this.right.toString(),")"].join(" ")}}const re={"+":t=>t,"-":t=>-t,"~":t=>~t};class ae{constructor(t,e){this.operator=t,this.expression=e}evaluate(){const t=re[this.operator];if(!t)throw new Error(`unexpected unary operator: '${this.operator}`);return t(this.expression.evaluate())}toString(){return["u(",this.operator,this.expression.toString(),")"].join(" ")}}function le(t){return(e,n)=>{for(let i=0;ie.startsWith(t,n)))[0];return i?(n+=i.length,{cursor:n+=pe(e,n).length,operator:i}):null}const _e=[["**"],["*","/","%"],["+","-"],["<<",">>>",">>"],["&"],["^"],["|"]].reduce(((t,e)=>function(t,e){return(n,i)=>{const s=t(n,i);if(!s)return null;i=s.cursor;let o=s.evaluable;for(;;){const s=ge(e,n,i);if(!s)break;i=s.cursor;const r=t(n,i);if(!r)return null;i=r.cursor,o=new oe(s.operator,o,r.evaluable)}return o?{cursor:i,evaluable:o}:null}}(t,e)),(function t(e,n){const i=be(e,n);if(i)return i;const s=e.substr(n,1);if(n+=s.length,"+"!==s&&"-"!==s&&"~"!==s)return null;const o=t(e,n);return o?{cursor:n=o.cursor,evaluable:new ae(s,o.evaluable)}:null}));function fe(t,e){return e+=pe(t,e).length,_e(t,e)}function we(t){var e;const n=function(t){const e=fe(t,0);return e?e.cursor+pe(t,e.cursor).length!==t.length?null:e.evaluable:null}(t);return null!==(e=null==n?void 0:n.evaluate())&&void 0!==e?e:null}function xe(t){if("number"==typeof t)return t;if("string"==typeof t){const e=we(t);if(!r(e))return e}return 0}function ye(t){return String(t)}function Ce(t){return e=>e.toFixed(Math.max(Math.min(t,20),0))}const Pe=Ce(0);function Ee(t){return Pe(t)+"%"}function ke(t){return String(t)}function Ve(t){return t}function Se(t,e){for(;t.length{o((()=>{e.setRawValue(n(t,e),i.options)}))})),e.emitter.on("change",(s=>{o((()=>{t.setRawValue(i(t,e),s.options)})),o((()=>{e.setRawValue(n(t,e),s.options)}))})),o((()=>{e.setRawValue(n(t,e),{forceEmit:!1,last:!0})}))}function Ie(t,e){const n=t*(e.altKey?.1:1)*(e.shiftKey?10:1);return e.upKey?+n:e.downKey?-n:0}function Te(t){return{altKey:t.altKey,downKey:"ArrowDown"===t.key,shiftKey:t.shiftKey,upKey:"ArrowUp"===t.key}}function De(t){return{altKey:t.altKey,downKey:"ArrowLeft"===t.key,shiftKey:t.shiftKey,upKey:"ArrowRight"===t.key}}function je(t){return function(t){return"ArrowUp"===t||"ArrowDown"===t}(t)||"ArrowLeft"===t||"ArrowRight"===t}function Be(t,e){const n=e.ownerDocument.defaultView,i=e.getBoundingClientRect();return{x:t.pageX-((n&&n.scrollX||0)+i.left),y:t.pageY-((n&&n.scrollY||0)+i.top)}}class Re{constructor(t){this.lastTouch_=null,this.onDocumentMouseMove_=this.onDocumentMouseMove_.bind(this),this.onDocumentMouseUp_=this.onDocumentMouseUp_.bind(this),this.onMouseDown_=this.onMouseDown_.bind(this),this.onTouchEnd_=this.onTouchEnd_.bind(this),this.onTouchMove_=this.onTouchMove_.bind(this),this.onTouchStart_=this.onTouchStart_.bind(this),this.elem_=t,this.emitter=new h,t.addEventListener("touchstart",this.onTouchStart_,{passive:!1}),t.addEventListener("touchmove",this.onTouchMove_,{passive:!0}),t.addEventListener("touchend",this.onTouchEnd_),t.addEventListener("mousedown",this.onMouseDown_)}computePosition_(t){const e=this.elem_.getBoundingClientRect();return{bounds:{width:e.width,height:e.height},point:t?{x:t.x,y:t.y}:null}}onMouseDown_(t){var e;t.preventDefault(),null===(e=t.currentTarget)||void 0===e||e.focus();const n=this.elem_.ownerDocument;n.addEventListener("mousemove",this.onDocumentMouseMove_),n.addEventListener("mouseup",this.onDocumentMouseUp_),this.emitter.emit("down",{altKey:t.altKey,data:this.computePosition_(Be(t,this.elem_)),sender:this,shiftKey:t.shiftKey})}onDocumentMouseMove_(t){this.emitter.emit("move",{altKey:t.altKey,data:this.computePosition_(Be(t,this.elem_)),sender:this,shiftKey:t.shiftKey})}onDocumentMouseUp_(t){const e=this.elem_.ownerDocument;e.removeEventListener("mousemove",this.onDocumentMouseMove_),e.removeEventListener("mouseup",this.onDocumentMouseUp_),this.emitter.emit("up",{altKey:t.altKey,data:this.computePosition_(Be(t,this.elem_)),sender:this,shiftKey:t.shiftKey})}onTouchStart_(t){t.preventDefault();const e=t.targetTouches.item(0),n=this.elem_.getBoundingClientRect();this.emitter.emit("down",{altKey:t.altKey,data:this.computePosition_(e?{x:e.clientX-n.left,y:e.clientY-n.top}:void 0),sender:this,shiftKey:t.shiftKey}),this.lastTouch_=e}onTouchMove_(t){const e=t.targetTouches.item(0),n=this.elem_.getBoundingClientRect();this.emitter.emit("move",{altKey:t.altKey,data:this.computePosition_(e?{x:e.clientX-n.left,y:e.clientY-n.top}:void 0),sender:this,shiftKey:t.shiftKey}),this.lastTouch_=e}onTouchEnd_(t){var e;const n=null!==(e=t.targetTouches.item(0))&&void 0!==e?e:this.lastTouch_,i=this.elem_.getBoundingClientRect();this.emitter.emit("up",{altKey:t.altKey,data:this.computePosition_(n?{x:n.clientX-i.left,y:n.clientY-i.top}:void 0),sender:this,shiftKey:t.shiftKey})}}function Fe(t,e,n,i,s){return i+(t-e)/(n-e)*(s-i)}function Ue(t){return String(t.toFixed(10)).split(".")[1].replace(/0+$/,"").length}function Oe(t,e,n){return Math.min(Math.max(t,e),n)}function Ke(t,e){return(t%e+e)%e}const Ne=v("txt");class $e{constructor(t,e){this.onChange_=this.onChange_.bind(this),this.props_=e.props,this.props_.emitter.on("change",this.onChange_),this.element=t.createElement("div"),this.element.classList.add(Ne(),Ne(void 0,"num")),e.arrayPosition&&this.element.classList.add(Ne(void 0,e.arrayPosition)),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("input");n.classList.add(Ne("i")),n.type="text",e.viewProps.bindDisabled(n),this.element.appendChild(n),this.inputElement=n,this.onDraggingChange_=this.onDraggingChange_.bind(this),this.dragging_=e.dragging,this.dragging_.emitter.on("change",this.onDraggingChange_),this.element.classList.add(Ne()),this.inputElement.classList.add(Ne("i"));const i=t.createElement("div");i.classList.add(Ne("k")),this.element.appendChild(i),this.knobElement=i;const s=t.createElementNS(D,"svg");s.classList.add(Ne("g")),this.knobElement.appendChild(s);const o=t.createElementNS(D,"path");o.classList.add(Ne("gb")),s.appendChild(o),this.guideBodyElem_=o;const r=t.createElementNS(D,"path");r.classList.add(Ne("gh")),s.appendChild(r),this.guideHeadElem_=r;const a=t.createElement("div");a.classList.add(v("tt")()),this.knobElement.appendChild(a),this.tooltipElem_=a,e.value.emitter.on("change",this.onChange_),this.value=e.value,this.refresh()}onDraggingChange_(t){if(null===t.rawValue)return void this.element.classList.remove(Ne(void 0,"drg"));this.element.classList.add(Ne(void 0,"drg"));const e=t.rawValue/this.props_.get("draggingScale"),n=e+(e>0?-1:e<0?1:0),i=Oe(-n,-4,4);this.guideHeadElem_.setAttributeNS(null,"d",[`M ${n+i},0 L${n},4 L${n+i},8`,`M ${e},-1 L${e},9`].join(" ")),this.guideBodyElem_.setAttributeNS(null,"d",`M 0,4 L${e},4`);const s=this.props_.get("formatter");this.tooltipElem_.textContent=s(this.value.rawValue),this.tooltipElem_.style.left=`${e}px`}refresh(){const t=this.props_.get("formatter");this.inputElement.value=t(this.value.rawValue)}onChange_(){this.refresh()}}class ze{constructor(t,e){this.originRawValue_=0,this.onInputChange_=this.onInputChange_.bind(this),this.onInputKeyDown_=this.onInputKeyDown_.bind(this),this.onInputKeyUp_=this.onInputKeyUp_.bind(this),this.onPointerDown_=this.onPointerDown_.bind(this),this.onPointerMove_=this.onPointerMove_.bind(this),this.onPointerUp_=this.onPointerUp_.bind(this),this.baseStep_=e.baseStep,this.parser_=e.parser,this.props=e.props,this.value=e.value,this.viewProps=e.viewProps,this.dragging_=E(null),this.view=new $e(t,{arrayPosition:e.arrayPosition,dragging:this.dragging_,props:this.props,value:this.value,viewProps:this.viewProps}),this.view.inputElement.addEventListener("change",this.onInputChange_),this.view.inputElement.addEventListener("keydown",this.onInputKeyDown_),this.view.inputElement.addEventListener("keyup",this.onInputKeyUp_);const n=new Re(this.view.knobElement);n.emitter.on("down",this.onPointerDown_),n.emitter.on("move",this.onPointerMove_),n.emitter.on("up",this.onPointerUp_)}onInputChange_(t){const e=t.currentTarget.value,n=this.parser_(e);r(n)||(this.value.rawValue=n),this.view.refresh()}onInputKeyDown_(t){const e=Ie(this.baseStep_,Te(t));0!==e&&this.value.setRawValue(this.value.rawValue+e,{forceEmit:!1,last:!1})}onInputKeyUp_(t){0!==Ie(this.baseStep_,Te(t))&&this.value.setRawValue(this.value.rawValue,{forceEmit:!0,last:!0})}onPointerDown_(){this.originRawValue_=this.value.rawValue,this.dragging_.rawValue=0}computeDraggingValue_(t){if(!t.point)return null;const e=t.point.x-t.bounds.width/2;return this.originRawValue_+e*this.props.get("draggingScale")}onPointerMove_(t){const e=this.computeDraggingValue_(t.data);null!==e&&(this.value.setRawValue(e,{forceEmit:!1,last:!1}),this.dragging_.rawValue=this.value.rawValue-this.originRawValue_)}onPointerUp_(t){const e=this.computeDraggingValue_(t.data);null!==e&&(this.value.setRawValue(e,{forceEmit:!0,last:!0}),this.dragging_.rawValue=null)}}const He=v("sld");class qe{constructor(t,e){this.onChange_=this.onChange_.bind(this),this.props_=e.props,this.props_.emitter.on("change",this.onChange_),this.element=t.createElement("div"),this.element.classList.add(He()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("div");n.classList.add(He("t")),e.viewProps.bindTabIndex(n),this.element.appendChild(n),this.trackElement=n;const i=t.createElement("div");i.classList.add(He("k")),this.trackElement.appendChild(i),this.knobElement=i,e.value.emitter.on("change",this.onChange_),this.value=e.value,this.update_()}update_(){const t=Oe(Fe(this.value.rawValue,this.props_.get("minValue"),this.props_.get("maxValue"),0,100),0,100);this.knobElement.style.width=`${t}%`}onChange_(){this.update_()}}class Ge{constructor(t,e){this.onKeyDown_=this.onKeyDown_.bind(this),this.onKeyUp_=this.onKeyUp_.bind(this),this.onPointerDownOrMove_=this.onPointerDownOrMove_.bind(this),this.onPointerUp_=this.onPointerUp_.bind(this),this.baseStep_=e.baseStep,this.value=e.value,this.viewProps=e.viewProps,this.props=e.props,this.view=new qe(t,{props:this.props,value:this.value,viewProps:this.viewProps}),this.ptHandler_=new Re(this.view.trackElement),this.ptHandler_.emitter.on("down",this.onPointerDownOrMove_),this.ptHandler_.emitter.on("move",this.onPointerDownOrMove_),this.ptHandler_.emitter.on("up",this.onPointerUp_),this.view.trackElement.addEventListener("keydown",this.onKeyDown_),this.view.trackElement.addEventListener("keyup",this.onKeyUp_)}handlePointerEvent_(t,e){t.point&&this.value.setRawValue(Fe(Oe(t.point.x,0,t.bounds.width),0,t.bounds.width,this.props.get("minValue"),this.props.get("maxValue")),e)}onPointerDownOrMove_(t){this.handlePointerEvent_(t.data,{forceEmit:!1,last:!1})}onPointerUp_(t){this.handlePointerEvent_(t.data,{forceEmit:!0,last:!0})}onKeyDown_(t){const e=Ie(this.baseStep_,De(t));0!==e&&this.value.setRawValue(this.value.rawValue+e,{forceEmit:!1,last:!1})}onKeyUp_(t){0!==Ie(this.baseStep_,De(t))&&this.value.setRawValue(this.value.rawValue,{forceEmit:!0,last:!0})}}const Ye=v("sldtxt");class We{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(Ye());const n=t.createElement("div");n.classList.add(Ye("s")),this.sliderView_=e.sliderView,n.appendChild(this.sliderView_.element),this.element.appendChild(n);const i=t.createElement("div");i.classList.add(Ye("t")),this.textView_=e.textView,i.appendChild(this.textView_.element),this.element.appendChild(i)}}class Xe{constructor(t,e){this.value=e.value,this.viewProps=e.viewProps,this.sliderC_=new Ge(t,{baseStep:e.baseStep,props:e.sliderProps,value:e.value,viewProps:this.viewProps}),this.textC_=new ze(t,{baseStep:e.baseStep,parser:e.parser,props:e.textProps,value:e.value,viewProps:e.viewProps}),this.view=new We(t,{sliderView:this.sliderC_.view,textView:this.textC_.view})}get sliderController(){return this.sliderC_}get textController(){return this.textC_}}function Qe(t,e){t.write(e)}function Je(t){const e=M;return Array.isArray(t)?e.required.array(e.required.object({text:e.required.string,value:e.required.raw}))(t).value:"object"==typeof t?e.required.raw(t).value:void 0}function Ze(t){if("inline"===t||"popup"===t)return t}function tn(t){const e=M;return e.required.object({max:e.optional.number,min:e.optional.number,step:e.optional.number})(t).value}function en(t){if(Array.isArray(t))return t;const e=[];return Object.keys(t).forEach((n=>{e.push({text:n,value:t[n]})})),e}function nn(t){return r(t)?null:new $t(en(t))}function sn(t){const e=t?Nt(t,$t):null;return e?e.options:null}function on(t,e){const n=t&&Nt(t,Ht);return n?Ue(n.step):Math.max(Ue(e),2)}function rn(t){const e=function(t){const e=t?Nt(t,Ht):null;return e?e.step:null}(t);return null!=e?e:1}function an(t,e){var n;const i=t&&Nt(t,Ht),s=Math.abs(null!==(n=null==i?void 0:i.step)&&void 0!==n?n:e);return 0===s?.1:Math.pow(10,Math.floor(Math.log10(s))-1)}const ln=v("ckb");class pn{constructor(t,e){this.onValueChange_=this.onValueChange_.bind(this),this.element=t.createElement("div"),this.element.classList.add(ln()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("label");n.classList.add(ln("l")),this.element.appendChild(n);const i=t.createElement("input");i.classList.add(ln("i")),i.type="checkbox",n.appendChild(i),this.inputElement=i,e.viewProps.bindDisabled(this.inputElement);const s=t.createElement("div");s.classList.add(ln("w")),n.appendChild(s);const o=U(t,"check");s.appendChild(o),e.value.emitter.on("change",this.onValueChange_),this.value=e.value,this.update_()}update_(){this.inputElement.checked=this.value.rawValue}onValueChange_(){this.update_()}}class dn{constructor(t,e){this.onInputChange_=this.onInputChange_.bind(this),this.value=e.value,this.viewProps=e.viewProps,this.view=new pn(t,{value:this.value,viewProps:this.viewProps}),this.view.inputElement.addEventListener("change",this.onInputChange_)}onInputChange_(t){const e=t.currentTarget;this.value.rawValue=e.checked}}const cn={id:"input-bool",type:"input",accept:(t,e)=>{if("boolean"!=typeof t)return null;const n=L(e,{options:M.optional.custom(Je)});return n?{initialValue:t,params:n}:null},binding:{reader:t=>ee,constraint:t=>function(t){const e=[],n=nn(t.options);return n&&e.push(n),new Kt(e)}(t.params),writer:t=>Qe},controller:t=>{var e;const n=t.document,i=t.value,s=t.constraint;return s&&Nt(s,$t)?new Yt(n,{props:k.fromObject({options:null!==(e=sn(s))&&void 0!==e?e:[]}),value:i,viewProps:t.viewProps}):new dn(n,{value:i,viewProps:t.viewProps})}},hn=v("col");class un{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(hn()),e.foldable.bindExpandedClass(this.element,hn(void 0,"expanded")),g(e.foldable,"completed",_(this.element,hn(void 0,"cpl")));const n=t.createElement("div");n.classList.add(hn("h")),this.element.appendChild(n);const i=t.createElement("div");i.classList.add(hn("s")),n.appendChild(i),this.swatchElement=i;const s=t.createElement("div");if(s.classList.add(hn("t")),n.appendChild(s),this.textElement=s,"inline"===e.pickerLayout){const e=t.createElement("div");e.classList.add(hn("p")),this.element.appendChild(e),this.pickerElement=e}else this.pickerElement=null}}function vn(t,e,n){const i=Ke(t,360),s=Oe(e/100,0,1),o=Oe(n/100,0,1),r=o*s,a=r*(1-Math.abs(i/60%2-1)),l=o-r;let p,d,c;return[p,d,c]=i>=0&&i<60?[r,a,0]:i>=60&&i<120?[a,r,0]:i>=120&&i<180?[0,r,a]:i>=180&&i<240?[0,a,r]:i>=240&&i<300?[a,0,r]:[r,0,a],[255*(p+l),255*(d+l),255*(c+l)]}function mn(t){return[t[0],t[1],t[2]]}function bn(t,e){return[t[0],t[1],t[2],e]}const gn={hsl:{hsl:(t,e,n)=>[t,e,n],hsv:function(t,e,n){const i=n+e*(100-Math.abs(2*n-100))/200;return[t,0!==i?e*(100-Math.abs(2*n-100))/i:0,n+e*(100-Math.abs(2*n-100))/200]},rgb:function(t,e,n){const i=(t%360+360)%360,s=Oe(e/100,0,1),o=Oe(n/100,0,1),r=(1-Math.abs(2*o-1))*s,a=r*(1-Math.abs(i/60%2-1)),l=o-r/2;let p,d,c;return[p,d,c]=i>=0&&i<60?[r,a,0]:i>=60&&i<120?[a,r,0]:i>=120&&i<180?[0,r,a]:i>=180&&i<240?[0,a,r]:i>=240&&i<300?[a,0,r]:[r,0,a],[255*(p+l),255*(d+l),255*(c+l)]}},hsv:{hsl:function(t,e,n){const i=100-Math.abs(n*(200-e)/100-100);return[t,0!==i?e*n/i:0,n*(200-e)/200]},hsv:(t,e,n)=>[t,e,n],rgb:vn},rgb:{hsl:function(t,e,n){const i=Oe(t/255,0,1),s=Oe(e/255,0,1),o=Oe(n/255,0,1),r=Math.max(i,s,o),a=Math.min(i,s,o),l=r-a;let p=0,d=0;const c=(a+r)/2;return 0!==l&&(d=l/(1-Math.abs(r+a-1)),p=i===r?(s-o)/l:s===r?2+(o-i)/l:4+(i-s)/l,p=p/6+(p<0?1:0)),[360*p,100*d,100*c]},hsv:function(t,e,n){const i=Oe(t/255,0,1),s=Oe(e/255,0,1),o=Oe(n/255,0,1),r=Math.max(i,s,o),a=r-Math.min(i,s,o);let l;return l=0===a?0:r===i?((s-o)/a%6+6)%6*60:r===s?60*((o-i)/a+2):60*((i-s)/a+4),[l,100*(0===r?0:a/r),100*r]},rgb:(t,e,n)=>[t,e,n]}};const _n={hsl:t=>{var e;return[Ke(t[0],360),Oe(t[1],0,100),Oe(t[2],0,100),Oe(null!==(e=t[3])&&void 0!==e?e:1,0,1)]},hsv:t=>{var e;return[Ke(t[0],360),Oe(t[1],0,100),Oe(t[2],0,100),Oe(null!==(e=t[3])&&void 0!==e?e:1,0,1)]},rgb:t=>{var e;return[Oe(t[0],0,255),Oe(t[1],0,255),Oe(t[2],0,255),Oe(null!==(e=t[3])&&void 0!==e?e:1,0,1)]}};function fn(t,e){return"object"==typeof t&&!r(t)&&e in t&&"number"==typeof t[e]}class wn{constructor(t,e){this.mode_=e,this.comps_=_n[e](t)}static black(){return new wn([0,0,0],"rgb")}static fromObject(t){const e="a"in t?[t.r,t.g,t.b,t.a]:[t.r,t.g,t.b];return new wn(e,"rgb")}static toRgbaObject(t){return t.toRgbaObject()}static isRgbColorObject(t){return fn(t,"r")&&fn(t,"g")&&fn(t,"b")}static isRgbaColorObject(t){return this.isRgbColorObject(t)&&fn(t,"a")}static isColorObject(t){return this.isRgbColorObject(t)}static equals(t,e){if(t.mode_!==e.mode_)return!1;const n=t.comps_,i=e.comps_;for(let t=0;tt.inputElement))];return this.alphaViews_&&t.push(this.alphaViews_.palette.element,this.alphaViews_.text.inputElement),t}}function Cn(t){const e=M;return L(t,{alpha:e.optional.boolean,expanded:e.optional.boolean,picker:e.optional.custom(Ze)})}function Pn(t){return t?.1:1}function En(t,e){const n=t.match(/^(.+)%$/);return n?Math.min(.01*parseFloat(n[1])*e,e):Math.min(parseFloat(t),e)}const kn={deg:t=>t,grad:t=>360*t/400,rad:t=>360*t/(2*Math.PI),turn:t=>360*t};function Vn(t){const e=t.match(/^([0-9.]+?)(deg|grad|rad|turn)$/);if(!e)return parseFloat(t);const n=parseFloat(e[1]),i=e[2];return kn[i](n)}const Sn={"func.rgb":t=>{const e=t.match(/^rgb\(\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/);if(!e)return null;const n=[En(e[1],255),En(e[2],255),En(e[3],255)];return isNaN(n[0])||isNaN(n[1])||isNaN(n[2])?null:new wn(n,"rgb")},"func.rgba":t=>{const e=t.match(/^rgba\(\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/);if(!e)return null;const n=[En(e[1],255),En(e[2],255),En(e[3],255),En(e[4],1)];return isNaN(n[0])||isNaN(n[1])||isNaN(n[2])||isNaN(n[3])?null:new wn(n,"rgb")},"func.hsl":t=>{const e=t.match(/^hsl\(\s*([0-9A-Fa-f.]+(?:deg|grad|rad|turn)?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/);if(!e)return null;const n=[Vn(e[1]),En(e[2],100),En(e[3],100)];return isNaN(n[0])||isNaN(n[1])||isNaN(n[2])?null:new wn(n,"hsl")},"func.hsla":t=>{const e=t.match(/^hsla\(\s*([0-9A-Fa-f.]+(?:deg|grad|rad|turn)?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/);if(!e)return null;const n=[Vn(e[1]),En(e[2],100),En(e[3],100),En(e[4],1)];return isNaN(n[0])||isNaN(n[1])||isNaN(n[2])||isNaN(n[3])?null:new wn(n,"hsl")},"hex.rgb":t=>{const e=t.match(/^#([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$/);if(e)return new wn([parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)],"rgb");const n=t.match(/^(?:#|0x)([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/);return n?new wn([parseInt(n[1],16),parseInt(n[2],16),parseInt(n[3],16)],"rgb"):null},"hex.rgba":t=>{const e=t.match(/^#?([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$/);if(e)return new wn([parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16),Fe(parseInt(e[4]+e[4],16),0,255,0,1)],"rgb");const n=t.match(/^(?:#|0x)?([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/);return n?new wn([parseInt(n[1],16),parseInt(n[2],16),parseInt(n[3],16),Fe(parseInt(n[4],16),0,255,0,1)],"rgb"):null}};function Mn(t){return Object.keys(Sn).reduce(((e,n)=>e||((0,Sn[n])(t)?n:null)),null)}const Ln=t=>{const e=Mn(t);return e?Sn[e](t):null};function An(t){return"func.hsla"===t||"func.rgba"===t||"hex.rgba"===t}function In(t){if("string"==typeof t){const e=Ln(t);if(e)return e}return wn.black()}function Tn(t){const e=Oe(Math.floor(t),0,255).toString(16);return 1===e.length?`0${e}`:e}function Dn(t,e="#"){return`${e}${mn(t.getComponents("rgb")).map(Tn).join("")}`}function jn(t,e="#"){const n=t.getComponents("rgb");return`${e}${[n[0],n[1],n[2],255*n[3]].map(Tn).join("")}`}function Bn(t){const e=Ce(0);return`rgb(${mn(t.getComponents("rgb")).map((t=>e(t))).join(", ")})`}function Rn(t){const e=Ce(2),n=Ce(0);return`rgba(${t.getComponents("rgb").map(((t,i)=>(3===i?e:n)(t))).join(", ")})`}const Fn={"func.hsl":function(t){const e=[Ce(0),Ee,Ee];return`hsl(${mn(t.getComponents("hsl")).map(((t,n)=>e[n](t))).join(", ")})`},"func.hsla":function(t){const e=[Ce(0),Ee,Ee,Ce(2)];return`hsla(${t.getComponents("hsl").map(((t,n)=>e[n](t))).join(", ")})`},"func.rgb":Bn,"func.rgba":Rn,"hex.rgb":Dn,"hex.rgba":jn};function Un(t){return Fn[t]}const On=v("apl");class Kn{constructor(t,e){this.onValueChange_=this.onValueChange_.bind(this),this.value=e.value,this.value.emitter.on("change",this.onValueChange_),this.element=t.createElement("div"),this.element.classList.add(On()),e.viewProps.bindTabIndex(this.element);const n=t.createElement("div");n.classList.add(On("b")),this.element.appendChild(n);const i=t.createElement("div");i.classList.add(On("c")),n.appendChild(i),this.colorElem_=i;const s=t.createElement("div");s.classList.add(On("m")),this.element.appendChild(s),this.markerElem_=s;const o=t.createElement("div");o.classList.add(On("p")),this.markerElem_.appendChild(o),this.previewElem_=o,this.update_()}update_(){const t=this.value.rawValue,e=t.getComponents("rgb"),n=new wn([e[0],e[1],e[2],0],"rgb"),i=new wn([e[0],e[1],e[2],255],"rgb"),s=["to right",Rn(n),Rn(i)];this.colorElem_.style.background=`linear-gradient(${s.join(",")})`,this.previewElem_.style.backgroundColor=Rn(t);const o=Fe(e[3],0,1,0,100);this.markerElem_.style.left=`${o}%`}onValueChange_(){this.update_()}}class Nn{constructor(t,e){this.onKeyDown_=this.onKeyDown_.bind(this),this.onKeyUp_=this.onKeyUp_.bind(this),this.onPointerDown_=this.onPointerDown_.bind(this),this.onPointerMove_=this.onPointerMove_.bind(this),this.onPointerUp_=this.onPointerUp_.bind(this),this.value=e.value,this.viewProps=e.viewProps,this.view=new Kn(t,{value:this.value,viewProps:this.viewProps}),this.ptHandler_=new Re(this.view.element),this.ptHandler_.emitter.on("down",this.onPointerDown_),this.ptHandler_.emitter.on("move",this.onPointerMove_),this.ptHandler_.emitter.on("up",this.onPointerUp_),this.view.element.addEventListener("keydown",this.onKeyDown_),this.view.element.addEventListener("keyup",this.onKeyUp_)}handlePointerEvent_(t,e){if(!t.point)return;const n=t.point.x/t.bounds.width,i=this.value.rawValue,[s,o,r]=i.getComponents("hsv");this.value.setRawValue(new wn([s,o,r,n],"hsv"),e)}onPointerDown_(t){this.handlePointerEvent_(t.data,{forceEmit:!1,last:!1})}onPointerMove_(t){this.handlePointerEvent_(t.data,{forceEmit:!1,last:!1})}onPointerUp_(t){this.handlePointerEvent_(t.data,{forceEmit:!0,last:!0})}onKeyDown_(t){const e=Ie(Pn(!0),De(t));if(0===e)return;const n=this.value.rawValue,[i,s,o,r]=n.getComponents("hsv");this.value.setRawValue(new wn([i,s,o,r+e],"hsv"),{forceEmit:!1,last:!1})}onKeyUp_(t){0!==Ie(Pn(!0),De(t))&&this.value.setRawValue(this.value.rawValue,{forceEmit:!0,last:!0})}}const $n=v("coltxt");class zn{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add($n());const n=t.createElement("div");n.classList.add($n("m")),this.modeElem_=function(t){const e=t.createElement("select");return e.appendChild([{text:"RGB",value:"rgb"},{text:"HSL",value:"hsl"},{text:"HSV",value:"hsv"}].reduce(((e,n)=>{const i=t.createElement("option");return i.textContent=n.text,i.value=n.value,e.appendChild(i),e}),t.createDocumentFragment())),e}(t),this.modeElem_.classList.add($n("ms")),n.appendChild(this.modeSelectElement);const i=t.createElement("div");i.classList.add($n("mm")),i.appendChild(U(t,"dropdown")),n.appendChild(i),this.element.appendChild(n);const s=t.createElement("div");s.classList.add($n("w")),this.element.appendChild(s),this.textsElem_=s,this.textViews_=e.textViews,this.applyTextViews_(),b(e.colorMode,(t=>{this.modeElem_.value=t}))}get modeSelectElement(){return this.modeElem_}get textViews(){return this.textViews_}set textViews(t){this.textViews_=t,this.applyTextViews_()}applyTextViews_(){N(this.textsElem_);const t=this.element.ownerDocument;this.textViews_.forEach((e=>{const n=t.createElement("div");n.classList.add($n("c")),n.appendChild(e.element),this.textsElem_.appendChild(n)}))}}const Hn=Ce(0),qn={rgb:()=>new zt({min:0,max:255}),hsl:t=>new zt(0===t?{min:0,max:360}:{min:0,max:100}),hsv:t=>new zt(0===t?{min:0,max:360}:{min:0,max:100})};function Gn(t,e,n){return new ze(t,{arrayPosition:0===n?"fst":2===n?"lst":"mid",baseStep:Pn(!1),parser:e.parser,props:k.fromObject({draggingScale:1,formatter:Hn}),value:E(0,{constraint:qn[e.colorMode](n)}),viewProps:e.viewProps})}class Yn{constructor(t,e){this.onModeSelectChange_=this.onModeSelectChange_.bind(this),this.parser_=e.parser,this.value=e.value,this.viewProps=e.viewProps,this.colorMode=E(this.value.rawValue.mode),this.ccs_=this.createComponentControllers_(t),this.view=new zn(t,{colorMode:this.colorMode,textViews:[this.ccs_[0].view,this.ccs_[1].view,this.ccs_[2].view]}),this.view.modeSelectElement.addEventListener("change",this.onModeSelectChange_)}createComponentControllers_(t){const e={colorMode:this.colorMode.rawValue,parser:this.parser_,viewProps:this.viewProps},n=[Gn(t,e,0),Gn(t,e,1),Gn(t,e,2)];return n.forEach(((t,e)=>{Ae({primary:this.value,secondary:t.value,forward:t=>t.rawValue.getComponents(this.colorMode.rawValue)[e],backward:(t,n)=>{const i=this.colorMode.rawValue,s=t.rawValue.getComponents(i);return s[e]=n.rawValue,new wn(bn(mn(s),s[3]),i)}})})),n}onModeSelectChange_(t){const e=t.currentTarget;this.colorMode.rawValue=e.value,this.ccs_=this.createComponentControllers_(this.view.element.ownerDocument),this.view.textViews=[this.ccs_[0].view,this.ccs_[1].view,this.ccs_[2].view]}}const Wn=v("hpl");class Xn{constructor(t,e){this.onValueChange_=this.onValueChange_.bind(this),this.value=e.value,this.value.emitter.on("change",this.onValueChange_),this.element=t.createElement("div"),this.element.classList.add(Wn()),e.viewProps.bindTabIndex(this.element);const n=t.createElement("div");n.classList.add(Wn("c")),this.element.appendChild(n);const i=t.createElement("div");i.classList.add(Wn("m")),this.element.appendChild(i),this.markerElem_=i,this.update_()}update_(){const t=this.value.rawValue,[e]=t.getComponents("hsv");this.markerElem_.style.backgroundColor=Bn(new wn([e,100,100],"hsv"));const n=Fe(e,0,360,0,100);this.markerElem_.style.left=`${n}%`}onValueChange_(){this.update_()}}class Qn{constructor(t,e){this.onKeyDown_=this.onKeyDown_.bind(this),this.onKeyUp_=this.onKeyUp_.bind(this),this.onPointerDown_=this.onPointerDown_.bind(this),this.onPointerMove_=this.onPointerMove_.bind(this),this.onPointerUp_=this.onPointerUp_.bind(this),this.value=e.value,this.viewProps=e.viewProps,this.view=new Xn(t,{value:this.value,viewProps:this.viewProps}),this.ptHandler_=new Re(this.view.element),this.ptHandler_.emitter.on("down",this.onPointerDown_),this.ptHandler_.emitter.on("move",this.onPointerMove_),this.ptHandler_.emitter.on("up",this.onPointerUp_),this.view.element.addEventListener("keydown",this.onKeyDown_),this.view.element.addEventListener("keyup",this.onKeyUp_)}handlePointerEvent_(t,e){if(!t.point)return;const n=Fe(t.point.x,0,t.bounds.width,0,360),i=this.value.rawValue,[,s,o,r]=i.getComponents("hsv");this.value.setRawValue(new wn([n,s,o,r],"hsv"),e)}onPointerDown_(t){this.handlePointerEvent_(t.data,{forceEmit:!1,last:!1})}onPointerMove_(t){this.handlePointerEvent_(t.data,{forceEmit:!1,last:!1})}onPointerUp_(t){this.handlePointerEvent_(t.data,{forceEmit:!0,last:!0})}onKeyDown_(t){const e=Ie(Pn(!1),De(t));if(0===e)return;const n=this.value.rawValue,[i,s,o,r]=n.getComponents("hsv");this.value.setRawValue(new wn([i+e,s,o,r],"hsv"),{forceEmit:!1,last:!1})}onKeyUp_(t){0!==Ie(Pn(!1),De(t))&&this.value.setRawValue(this.value.rawValue,{forceEmit:!0,last:!0})}}const Jn=v("svp");class Zn{constructor(t,e){this.onValueChange_=this.onValueChange_.bind(this),this.value=e.value,this.value.emitter.on("change",this.onValueChange_),this.element=t.createElement("div"),this.element.classList.add(Jn()),e.viewProps.bindTabIndex(this.element);const n=t.createElement("canvas");n.height=64,n.width=64,n.classList.add(Jn("c")),this.element.appendChild(n),this.canvasElement=n;const i=t.createElement("div");i.classList.add(Jn("m")),this.element.appendChild(i),this.markerElem_=i,this.update_()}update_(){const t=function(t){const e=t.ownerDocument.defaultView;return e&&"document"in e?t.getContext("2d"):null}(this.canvasElement);if(!t)return;const e=this.value.rawValue.getComponents("hsv"),n=this.canvasElement.width,i=this.canvasElement.height,s=t.getImageData(0,0,n,i),o=s.data;for(let t=0;tt.rawValue.getComponents()[3],backward:(t,e)=>{const n=t.rawValue.getComponents();return n[3]=e.rawValue,new wn(n,t.rawValue.mode)}}),this.textC_=new Yn(t,{parser:we,value:this.value,viewProps:this.viewProps}),this.view=new yn(t,{alphaViews:this.alphaIcs_?{palette:this.alphaIcs_.palette.view,text:this.alphaIcs_.text.view}:null,hPaletteView:this.hPaletteC_.view,supportsAlpha:e.supportsAlpha,svPaletteView:this.svPaletteC_.view,textView:this.textC_.view})}get textController(){return this.textC_}}const ni=v("colsw");class ii{constructor(t,e){this.onValueChange_=this.onValueChange_.bind(this),e.value.emitter.on("change",this.onValueChange_),this.value=e.value,this.element=t.createElement("div"),this.element.classList.add(ni()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("div");n.classList.add(ni("sw")),this.element.appendChild(n),this.swatchElem_=n;const i=t.createElement("button");i.classList.add(ni("b")),e.viewProps.bindDisabled(i),this.element.appendChild(i),this.buttonElement=i,this.update_()}update_(){const t=this.value.rawValue;this.swatchElem_.style.backgroundColor=jn(t)}onValueChange_(){this.update_()}}class si{constructor(t,e){this.value=e.value,this.viewProps=e.viewProps,this.view=new ii(t,{value:this.value,viewProps:this.viewProps})}}class oi{constructor(t,e){this.onButtonBlur_=this.onButtonBlur_.bind(this),this.onButtonClick_=this.onButtonClick_.bind(this),this.onPopupChildBlur_=this.onPopupChildBlur_.bind(this),this.onPopupChildKeydown_=this.onPopupChildKeydown_.bind(this),this.value=e.value,this.viewProps=e.viewProps,this.foldable_=X.create(e.expanded),this.swatchC_=new si(t,{value:this.value,viewProps:this.viewProps});const n=this.swatchC_.view.buttonElement;n.addEventListener("blur",this.onButtonBlur_),n.addEventListener("click",this.onButtonClick_),this.textC_=new te(t,{parser:e.parser,props:k.fromObject({formatter:e.formatter}),value:this.value,viewProps:this.viewProps}),this.view=new un(t,{foldable:this.foldable_,pickerLayout:e.pickerLayout}),this.view.swatchElement.appendChild(this.swatchC_.view.element),this.view.textElement.appendChild(this.textC_.view.element),this.popC_="popup"===e.pickerLayout?new Qt(t,{viewProps:this.viewProps}):null;const i=new ei(t,{supportsAlpha:e.supportsAlpha,value:this.value,viewProps:this.viewProps});i.view.allFocusableElements.forEach((t=>{t.addEventListener("blur",this.onPopupChildBlur_),t.addEventListener("keydown",this.onPopupChildKeydown_)})),this.pickerC_=i,this.popC_?(this.view.element.appendChild(this.popC_.view.element),this.popC_.view.element.appendChild(i.view.element),Ae({primary:this.foldable_.value("expanded"),secondary:this.popC_.shows,forward:t=>t.rawValue,backward:(t,e)=>e.rawValue})):this.view.pickerElement&&(this.view.pickerElement.appendChild(this.pickerC_.view.element),J(this.foldable_,this.view.pickerElement))}get textController(){return this.textC_}onButtonBlur_(t){if(!this.popC_)return;const e=this.view.element,n=t.relatedTarget;n&&e.contains(n)||(this.popC_.shows.rawValue=!1)}onButtonClick_(){this.foldable_.set("expanded",!this.foldable_.get("expanded")),this.foldable_.get("expanded")&&this.pickerC_.view.allFocusableElements[0].focus()}onPopupChildBlur_(t){if(!this.popC_)return;const e=this.popC_.view.element,n=$(t);n&&e.contains(n)||n&&n===this.swatchC_.view.buttonElement&&!B(e.ownerDocument)||(this.popC_.shows.rawValue=!1)}onPopupChildKeydown_(t){this.popC_?"Escape"===t.key&&(this.popC_.shows.rawValue=!1):this.view.pickerElement&&"Escape"===t.key&&this.swatchC_.view.buttonElement.focus()}}function ri(t){return wn.isColorObject(t)?wn.fromObject(t):wn.black()}function ai(t){return mn(t.getComponents("rgb")).reduce(((t,e)=>t<<8|255&Math.floor(e)),0)}function li(t){return t.getComponents("rgb").reduce(((t,e,n)=>t<<8|255&Math.floor(3===n?255*e:e)),0)>>>0}function pi(t){return"number"!=typeof t?wn.black():new wn([(e=t)>>16&255,e>>8&255,255&e],"rgb");var e}function di(t){return"number"!=typeof t?wn.black():new wn([(e=t)>>24&255,e>>16&255,e>>8&255,Fe(255&e,0,255,0,1)],"rgb");var e}function ci(t,e){const n=e.toRgbaObject();t.writeProperty("r",n.r),t.writeProperty("g",n.g),t.writeProperty("b",n.b),t.writeProperty("a",n.a)}function hi(t,e){const n=e.toRgbaObject();t.writeProperty("r",n.r),t.writeProperty("g",n.g),t.writeProperty("b",n.b)}function ui(t){return"alpha"in t&&!0===t.alpha}function vi(t){return t?t=>jn(t,"0x"):t=>Dn(t,"0x")}const mi={id:"input-color-number",type:"input",accept:(t,e)=>{if("number"!=typeof t)return null;if(!("view"in e))return null;if("color"!==e.view)return null;const n=Cn(e);return n?{initialValue:t,params:n}:null},binding:{reader:t=>ui(t.params)?di:pi,equals:wn.equals,writer:t=>function(t){const e=t?li:ai;return(t,n)=>{Qe(t,e(n))}}(ui(t.params))},controller:t=>{const e=ui(t.params),n="expanded"in t.params?t.params.expanded:void 0,i="picker"in t.params?t.params.picker:void 0;return new oi(t.document,{expanded:null!=n&&n,formatter:vi(e),parser:Ln,pickerLayout:null!=i?i:"popup",supportsAlpha:e,value:t.value,viewProps:t.viewProps})}};const bi={id:"input-color-object",type:"input",accept:(t,e)=>{if(!wn.isColorObject(t))return null;const n=Cn(e);return n?{initialValue:t,params:n}:null},binding:{reader:t=>ri,equals:wn.equals,writer:t=>{return e=t.initialValue,wn.isRgbaColorObject(e)?ci:hi;var e}},controller:t=>{const e=wn.isRgbaColorObject(t.initialValue),n="expanded"in t.params?t.params.expanded:void 0,i="picker"in t.params?t.params.picker:void 0,s=e?jn:Dn;return new oi(t.document,{expanded:null!=n&&n,formatter:s,parser:Ln,pickerLayout:null!=i?i:"popup",supportsAlpha:e,value:t.value,viewProps:t.viewProps})}},gi={id:"input-color-string",type:"input",accept:(t,e)=>{if("string"!=typeof t)return null;if("view"in e&&"text"===e.view)return null;if(!Mn(t))return null;const n=Cn(e);return n?{initialValue:t,params:n}:null},binding:{reader:t=>In,equals:wn.equals,writer:t=>{const e=Mn(t.initialValue);if(!e)throw p.shouldNeverHappen();return function(t){const e=Un(t);return(t,n)=>{Qe(t,e(n))}}(e)}},controller:t=>{const e=Mn(t.initialValue);if(!e)throw p.shouldNeverHappen();const n=Un(e),i="expanded"in t.params?t.params.expanded:void 0,s="picker"in t.params?t.params.picker:void 0;return new oi(t.document,{expanded:null!=i&&i,formatter:n,parser:Ln,pickerLayout:null!=s?s:"popup",supportsAlpha:An(e),value:t.value,viewProps:t.viewProps})}};class _i{constructor(t){this.components=t.components,this.asm_=t.assembly}constrain(t){const e=this.asm_.toComponents(t).map(((t,e)=>{var n,i;return null!==(i=null===(n=this.components[e])||void 0===n?void 0:n.constrain(t))&&void 0!==i?i:t}));return this.asm_.fromComponents(e)}}const fi=v("pndtxt");class wi{constructor(t,e){this.textViews=e.textViews,this.element=t.createElement("div"),this.element.classList.add(fi()),this.textViews.forEach((e=>{const n=t.createElement("div");n.classList.add(fi("a")),n.appendChild(e.element),this.element.appendChild(n)}))}}class xi{constructor(t,e){this.value=e.value,this.viewProps=e.viewProps,this.acs_=e.axes.map(((n,i)=>function(t,e,n){return new ze(t,{arrayPosition:0===n?"fst":n===e.axes.length-1?"lst":"mid",baseStep:e.axes[n].baseStep,parser:e.parser,props:e.axes[n].textProps,value:E(0,{constraint:e.axes[n].constraint}),viewProps:e.viewProps})}(t,e,i))),this.acs_.forEach(((t,n)=>{Ae({primary:this.value,secondary:t.value,forward:t=>e.assembly.toComponents(t.rawValue)[n],backward:(t,i)=>{const s=e.assembly.toComponents(t.rawValue);return s[n]=i.rawValue,e.assembly.fromComponents(s)}})})),this.view=new wi(t,{textViews:this.acs_.map((t=>t.view))})}}function yi(t){const e=[],n=function(t){return"step"in t&&!r(t.step)?new Ht(t.step):null}(t);n&&e.push(n);const i=function(t){return"max"in t&&!r(t.max)||"min"in t&&!r(t.min)?new zt({max:t.max,min:t.min}):null}(t);i&&e.push(i);const s=nn(t.options);return s&&e.push(s),new Kt(e)}function Ci(t){const[e,n]=function(t){const e=t?Nt(t,zt):null;return e?[e.minValue,e.maxValue]:[void 0,void 0]}(t);return[null!=e?e:0,null!=n?n:100]}const Pi={id:"input-number",type:"input",accept:(t,e)=>{if("number"!=typeof t)return null;const n=M,i=L(e,{format:n.optional.function,max:n.optional.number,min:n.optional.number,options:n.optional.custom(Je),step:n.optional.number});return i?{initialValue:t,params:i}:null},binding:{reader:t=>xe,constraint:t=>yi(t.params),writer:t=>Qe},controller:t=>{var e,n;const i=t.value,s=t.constraint;if(s&&Nt(s,$t))return new Yt(t.document,{props:k.fromObject({options:null!==(e=sn(s))&&void 0!==e?e:[]}),value:i,viewProps:t.viewProps});const o=null!==(n="format"in t.params?t.params.format:void 0)&&void 0!==n?n:Ce(on(s,i.rawValue));if(s&&Nt(s,zt)){const[e,n]=Ci(s);return new Xe(t.document,{baseStep:rn(s),parser:we,sliderProps:k.fromObject({maxValue:n,minValue:e}),textProps:k.fromObject({draggingScale:an(s,i.rawValue),formatter:o}),value:i,viewProps:t.viewProps})}return new ze(t.document,{baseStep:rn(s),parser:we,props:k.fromObject({draggingScale:an(s,i.rawValue),formatter:o}),value:i,viewProps:t.viewProps})}};class Ei{constructor(t=0,e=0){this.x=t,this.y=e}getComponents(){return[this.x,this.y]}static isObject(t){if(r(t))return!1;const e=t.x,n=t.y;return"number"==typeof e&&"number"==typeof n}static equals(t,e){return t.x===e.x&&t.y===e.y}toObject(){return{x:this.x,y:this.y}}}const ki={toComponents:t=>t.getComponents(),fromComponents:t=>new Ei(...t)},Vi=v("p2d");class Si{constructor(t,e){this.element=t.createElement("div"),this.element.classList.add(Vi()),e.viewProps.bindClassModifiers(this.element),b(e.expanded,_(this.element,Vi(void 0,"expanded")));const n=t.createElement("div");n.classList.add(Vi("h")),this.element.appendChild(n);const i=t.createElement("button");i.classList.add(Vi("b")),i.appendChild(U(t,"p2dpad")),e.viewProps.bindDisabled(i),n.appendChild(i),this.buttonElement=i;const s=t.createElement("div");if(s.classList.add(Vi("t")),n.appendChild(s),this.textElement=s,"inline"===e.pickerLayout){const e=t.createElement("div");e.classList.add(Vi("p")),this.element.appendChild(e),this.pickerElement=e}else this.pickerElement=null}}const Mi=v("p2dp");class Li{constructor(t,e){this.onFoldableChange_=this.onFoldableChange_.bind(this),this.onValueChange_=this.onValueChange_.bind(this),this.invertsY_=e.invertsY,this.maxValue_=e.maxValue,this.element=t.createElement("div"),this.element.classList.add(Mi()),"popup"===e.layout&&this.element.classList.add(Mi(void 0,"p"));const n=t.createElement("div");n.classList.add(Mi("p")),e.viewProps.bindTabIndex(n),this.element.appendChild(n),this.padElement=n;const i=t.createElementNS(D,"svg");i.classList.add(Mi("g")),this.padElement.appendChild(i),this.svgElem_=i;const s=t.createElementNS(D,"line");s.classList.add(Mi("ax")),s.setAttributeNS(null,"x1","0"),s.setAttributeNS(null,"y1","50%"),s.setAttributeNS(null,"x2","100%"),s.setAttributeNS(null,"y2","50%"),this.svgElem_.appendChild(s);const o=t.createElementNS(D,"line");o.classList.add(Mi("ax")),o.setAttributeNS(null,"x1","50%"),o.setAttributeNS(null,"y1","0"),o.setAttributeNS(null,"x2","50%"),o.setAttributeNS(null,"y2","100%"),this.svgElem_.appendChild(o);const r=t.createElementNS(D,"line");r.classList.add(Mi("l")),r.setAttributeNS(null,"x1","50%"),r.setAttributeNS(null,"y1","50%"),this.svgElem_.appendChild(r),this.lineElem_=r;const a=t.createElement("div");a.classList.add(Mi("m")),this.padElement.appendChild(a),this.markerElem_=a,e.value.emitter.on("change",this.onValueChange_),this.value=e.value,this.update_()}get allFocusableElements(){return[this.padElement]}update_(){const[t,e]=this.value.rawValue.getComponents(),n=this.maxValue_,i=Fe(t,-n,+n,0,100),s=Fe(e,-n,+n,0,100),o=this.invertsY_?100-s:s;this.lineElem_.setAttributeNS(null,"x2",`${i}%`),this.lineElem_.setAttributeNS(null,"y2",`${o}%`),this.markerElem_.style.left=`${i}%`,this.markerElem_.style.top=`${o}%`}onValueChange_(){this.update_()}onFoldableChange_(){this.update_()}}function Ai(t,e,n){return[Ie(e[0],De(t)),Ie(e[1],Te(t))*(n?1:-1)]}class Ii{constructor(t,e){this.onPadKeyDown_=this.onPadKeyDown_.bind(this),this.onPadKeyUp_=this.onPadKeyUp_.bind(this),this.onPointerDown_=this.onPointerDown_.bind(this),this.onPointerMove_=this.onPointerMove_.bind(this),this.onPointerUp_=this.onPointerUp_.bind(this),this.value=e.value,this.viewProps=e.viewProps,this.baseSteps_=e.baseSteps,this.maxValue_=e.maxValue,this.invertsY_=e.invertsY,this.view=new Li(t,{invertsY:this.invertsY_,layout:e.layout,maxValue:this.maxValue_,value:this.value,viewProps:this.viewProps}),this.ptHandler_=new Re(this.view.padElement),this.ptHandler_.emitter.on("down",this.onPointerDown_),this.ptHandler_.emitter.on("move",this.onPointerMove_),this.ptHandler_.emitter.on("up",this.onPointerUp_),this.view.padElement.addEventListener("keydown",this.onPadKeyDown_),this.view.padElement.addEventListener("keyup",this.onPadKeyUp_)}handlePointerEvent_(t,e){if(!t.point)return;const n=this.maxValue_,i=Fe(t.point.x,0,t.bounds.width,-n,+n),s=Fe(this.invertsY_?t.bounds.height-t.point.y:t.point.y,0,t.bounds.height,-n,+n);this.value.setRawValue(new Ei(i,s),e)}onPointerDown_(t){this.handlePointerEvent_(t.data,{forceEmit:!1,last:!1})}onPointerMove_(t){this.handlePointerEvent_(t.data,{forceEmit:!1,last:!1})}onPointerUp_(t){this.handlePointerEvent_(t.data,{forceEmit:!0,last:!0})}onPadKeyDown_(t){je(t.key)&&t.preventDefault();const[e,n]=Ai(t,this.baseSteps_,this.invertsY_);0===e&&0===n||this.value.setRawValue(new Ei(this.value.rawValue.x+e,this.value.rawValue.y+n),{forceEmit:!1,last:!1})}onPadKeyUp_(t){const[e,n]=Ai(t,this.baseSteps_,this.invertsY_);0===e&&0===n||this.value.setRawValue(this.value.rawValue,{forceEmit:!0,last:!0})}}class Ti{constructor(t,e){var n,i;this.onPopupChildBlur_=this.onPopupChildBlur_.bind(this),this.onPopupChildKeydown_=this.onPopupChildKeydown_.bind(this),this.onPadButtonBlur_=this.onPadButtonBlur_.bind(this),this.onPadButtonClick_=this.onPadButtonClick_.bind(this),this.value=e.value,this.viewProps=e.viewProps,this.foldable_=X.create(e.expanded),this.popC_="popup"===e.pickerLayout?new Qt(t,{viewProps:this.viewProps}):null;const s=new Ii(t,{baseSteps:[e.axes[0].baseStep,e.axes[1].baseStep],invertsY:e.invertsY,layout:e.pickerLayout,maxValue:e.maxValue,value:this.value,viewProps:this.viewProps});s.view.allFocusableElements.forEach((t=>{t.addEventListener("blur",this.onPopupChildBlur_),t.addEventListener("keydown",this.onPopupChildKeydown_)})),this.pickerC_=s,this.textC_=new xi(t,{assembly:ki,axes:e.axes,parser:e.parser,value:this.value,viewProps:this.viewProps}),this.view=new Si(t,{expanded:this.foldable_.value("expanded"),pickerLayout:e.pickerLayout,viewProps:this.viewProps}),this.view.textElement.appendChild(this.textC_.view.element),null===(n=this.view.buttonElement)||void 0===n||n.addEventListener("blur",this.onPadButtonBlur_),null===(i=this.view.buttonElement)||void 0===i||i.addEventListener("click",this.onPadButtonClick_),this.popC_?(this.view.element.appendChild(this.popC_.view.element),this.popC_.view.element.appendChild(this.pickerC_.view.element),Ae({primary:this.foldable_.value("expanded"),secondary:this.popC_.shows,forward:t=>t.rawValue,backward:(t,e)=>e.rawValue})):this.view.pickerElement&&(this.view.pickerElement.appendChild(this.pickerC_.view.element),J(this.foldable_,this.view.pickerElement))}onPadButtonBlur_(t){if(!this.popC_)return;const e=this.view.element,n=t.relatedTarget;n&&e.contains(n)||(this.popC_.shows.rawValue=!1)}onPadButtonClick_(){this.foldable_.set("expanded",!this.foldable_.get("expanded")),this.foldable_.get("expanded")&&this.pickerC_.view.allFocusableElements[0].focus()}onPopupChildBlur_(t){if(!this.popC_)return;const e=this.popC_.view.element,n=$(t);n&&e.contains(n)||n&&n===this.view.buttonElement&&!B(e.ownerDocument)||(this.popC_.shows.rawValue=!1)}onPopupChildKeydown_(t){this.popC_?"Escape"===t.key&&(this.popC_.shows.rawValue=!1):this.view.pickerElement&&"Escape"===t.key&&this.view.buttonElement.focus()}}function Di(t){return Ei.isObject(t)?new Ei(t.x,t.y):new Ei}function ji(t,e){t.writeProperty("x",e.x),t.writeProperty("y",e.y)}function Bi(t){if(!t)return;const e=[];return r(t.step)||e.push(new Ht(t.step)),r(t.max)&&r(t.min)||e.push(new zt({max:t.max,min:t.min})),new Kt(e)}function Ri(t,e){const n=t&&Nt(t,zt);if(n)return Math.max(Math.abs(n.minValue||0),Math.abs(n.maxValue||0));const i=rn(t);return Math.max(10*Math.abs(i),10*Math.abs(e))}function Fi(t,e){const n=e instanceof _i?e.components[0]:void 0,i=e instanceof _i?e.components[1]:void 0,s=Ri(n,t.x),o=Ri(i,t.y);return Math.max(s,o)}function Ui(t,e){return{baseStep:rn(e),constraint:e,textProps:k.fromObject({draggingScale:an(e,t),formatter:Ce(on(e,t))})}}function Oi(t){if(!("y"in t))return!1;const e=t.y;return!!e&&"inverted"in e&&!!e.inverted}const Ki={id:"input-point2d",type:"input",accept:(t,e)=>{if(!Ei.isObject(t))return null;const n=M,i=L(e,{expanded:n.optional.boolean,picker:n.optional.custom(Ze),x:n.optional.custom(tn),y:n.optional.object({inverted:n.optional.boolean,max:n.optional.number,min:n.optional.number,step:n.optional.number})});return i?{initialValue:t,params:i}:null},binding:{reader:t=>Di,constraint:t=>{return e=t.params,new _i({assembly:ki,components:[Bi("x"in e?e.x:void 0),Bi("y"in e?e.y:void 0)]});var e},equals:Ei.equals,writer:t=>ji},controller:t=>{const e=t.document,n=t.value,i=t.constraint;if(!(i instanceof _i))throw p.shouldNeverHappen();const s="expanded"in t.params?t.params.expanded:void 0,o="picker"in t.params?t.params.picker:void 0;return new Ti(e,{axes:[Ui(n.rawValue.x,i.components[0]),Ui(n.rawValue.y,i.components[1])],expanded:null!=s&&s,invertsY:Oi(t.params),maxValue:Fi(n.rawValue,i),parser:we,pickerLayout:null!=o?o:"popup",value:n,viewProps:t.viewProps})}};class Ni{constructor(t=0,e=0,n=0){this.x=t,this.y=e,this.z=n}getComponents(){return[this.x,this.y,this.z]}static isObject(t){if(r(t))return!1;const e=t.x,n=t.y,i=t.z;return"number"==typeof e&&"number"==typeof n&&"number"==typeof i}static equals(t,e){return t.x===e.x&&t.y===e.y&&t.z===e.z}toObject(){return{x:this.x,y:this.y,z:this.z}}}const $i={toComponents:t=>t.getComponents(),fromComponents:t=>new Ni(...t)};function zi(t){return Ni.isObject(t)?new Ni(t.x,t.y,t.z):new Ni}function Hi(t,e){t.writeProperty("x",e.x),t.writeProperty("y",e.y),t.writeProperty("z",e.z)}function qi(t){if(!t)return;const e=[];return r(t.step)||e.push(new Ht(t.step)),r(t.max)&&r(t.min)||e.push(new zt({max:t.max,min:t.min})),new Kt(e)}function Gi(t,e){return{baseStep:rn(e),constraint:e,textProps:k.fromObject({draggingScale:an(e,t),formatter:Ce(on(e,t))})}}const Yi={id:"input-point3d",type:"input",accept:(t,e)=>{if(!Ni.isObject(t))return null;const n=M,i=L(e,{x:n.optional.custom(tn),y:n.optional.custom(tn),z:n.optional.custom(tn)});return i?{initialValue:t,params:i}:null},binding:{reader:t=>zi,constraint:t=>{return e=t.params,new _i({assembly:$i,components:[qi("x"in e?e.x:void 0),qi("y"in e?e.y:void 0),qi("z"in e?e.z:void 0)]});var e},equals:Ni.equals,writer:t=>Hi},controller:t=>{const e=t.value,n=t.constraint;if(!(n instanceof _i))throw p.shouldNeverHappen();return new xi(t.document,{assembly:$i,axes:[Gi(e.rawValue.x,n.components[0]),Gi(e.rawValue.y,n.components[1]),Gi(e.rawValue.z,n.components[2])],parser:we,value:e,viewProps:t.viewProps})}};class Wi{constructor(t=0,e=0,n=0,i=0){this.x=t,this.y=e,this.z=n,this.w=i}getComponents(){return[this.x,this.y,this.z,this.w]}static isObject(t){if(r(t))return!1;const e=t.x,n=t.y,i=t.z,s=t.w;return"number"==typeof e&&"number"==typeof n&&"number"==typeof i&&"number"==typeof s}static equals(t,e){return t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w}toObject(){return{x:this.x,y:this.y,z:this.z,w:this.w}}}const Xi={toComponents:t=>t.getComponents(),fromComponents:t=>new Wi(...t)};function Qi(t){return Wi.isObject(t)?new Wi(t.x,t.y,t.z,t.w):new Wi}function Ji(t,e){t.writeProperty("x",e.x),t.writeProperty("y",e.y),t.writeProperty("z",e.z),t.writeProperty("w",e.w)}function Zi(t){if(!t)return;const e=[];return r(t.step)||e.push(new Ht(t.step)),r(t.max)&&r(t.min)||e.push(new zt({max:t.max,min:t.min})),new Kt(e)}const ts={id:"input-point4d",type:"input",accept:(t,e)=>{if(!Wi.isObject(t))return null;const n=M,i=L(e,{x:n.optional.custom(tn),y:n.optional.custom(tn),z:n.optional.custom(tn),w:n.optional.custom(tn)});return i?{initialValue:t,params:i}:null},binding:{reader:t=>Qi,constraint:t=>{return e=t.params,new _i({assembly:Xi,components:[Zi("x"in e?e.x:void 0),Zi("y"in e?e.y:void 0),Zi("z"in e?e.z:void 0),Zi("w"in e?e.w:void 0)]});var e},equals:Wi.equals,writer:t=>Ji},controller:t=>{const e=t.value,n=t.constraint;if(!(n instanceof _i))throw p.shouldNeverHappen();return new xi(t.document,{assembly:Xi,axes:e.rawValue.getComponents().map(((t,e)=>{return i=t,{baseStep:rn(s=n.components[e]),constraint:s,textProps:k.fromObject({draggingScale:an(s,i),formatter:Ce(on(s,i))})};var i,s})),parser:we,value:e,viewProps:t.viewProps})}};const es={id:"input-string",type:"input",accept:(t,e)=>{if("string"!=typeof t)return null;const n=L(e,{options:M.optional.custom(Je)});return n?{initialValue:t,params:n}:null},binding:{reader:t=>ke,constraint:t=>function(t){const e=[],n=nn(t.options);return n&&e.push(n),new Kt(e)}(t.params),writer:t=>Qe},controller:t=>{var e;const n=t.document,i=t.value,s=t.constraint;return s&&Nt(s,$t)?new Yt(n,{props:k.fromObject({options:null!==(e=sn(s))&&void 0!==e?e:[]}),value:i,viewProps:t.viewProps}):new te(n,{parser:t=>t,props:k.fromObject({formatter:Ve}),value:i,viewProps:t.viewProps})}},ns={defaultInterval:200,defaultLineCount:3},is=v("mll");class ss{constructor(t,e){this.onValueUpdate_=this.onValueUpdate_.bind(this),this.formatter_=e.formatter,this.element=t.createElement("div"),this.element.classList.add(is()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("textarea");n.classList.add(is("i")),n.style.height=`calc(var(--bld-us) * ${e.lineCount})`,n.readOnly=!0,e.viewProps.bindDisabled(n),this.element.appendChild(n),this.textareaElem_=n,e.value.emitter.on("change",this.onValueUpdate_),this.value=e.value,this.update_()}update_(){const t=this.textareaElem_,e=t.scrollTop===t.scrollHeight-t.clientHeight,n=[];this.value.rawValue.forEach((t=>{void 0!==t&&n.push(this.formatter_(t))})),t.textContent=n.join("\n"),e&&(t.scrollTop=t.scrollHeight)}onValueUpdate_(){this.update_()}}class os{constructor(t,e){this.value=e.value,this.viewProps=e.viewProps,this.view=new ss(t,{formatter:e.formatter,lineCount:e.lineCount,value:this.value,viewProps:this.viewProps})}}const rs=v("sgl");class as{constructor(t,e){this.onValueUpdate_=this.onValueUpdate_.bind(this),this.formatter_=e.formatter,this.element=t.createElement("div"),this.element.classList.add(rs()),e.viewProps.bindClassModifiers(this.element);const n=t.createElement("input");n.classList.add(rs("i")),n.readOnly=!0,n.type="text",e.viewProps.bindDisabled(n),this.element.appendChild(n),this.inputElement=n,e.value.emitter.on("change",this.onValueUpdate_),this.value=e.value,this.update_()}update_(){const t=this.value.rawValue,e=t[t.length-1];this.inputElement.value=void 0!==e?this.formatter_(e):""}onValueUpdate_(){this.update_()}}class ls{constructor(t,e){this.value=e.value,this.viewProps=e.viewProps,this.view=new as(t,{formatter:e.formatter,value:this.value,viewProps:this.viewProps})}}const ps={id:"monitor-bool",type:"monitor",accept:(t,e)=>{if("boolean"!=typeof t)return null;const n=L(e,{lineCount:M.optional.number});return n?{initialValue:t,params:n}:null},binding:{reader:t=>ee},controller:t=>{var e;return 1===t.value.rawValue.length?new ls(t.document,{formatter:ne,value:t.value,viewProps:t.viewProps}):new os(t.document,{formatter:ne,lineCount:null!==(e=t.params.lineCount)&&void 0!==e?e:ns.defaultLineCount,value:t.value,viewProps:t.viewProps})}};class ds{constructor(){this.emitter=new h,this.index_=-1}get index(){return this.index_}set index(t){this.index_!==t&&(this.index_=t,this.emitter.emit("change",{index:t,sender:this}))}}const cs=v("grl");class hs{constructor(t,e){this.onCursorChange_=this.onCursorChange_.bind(this),this.onValueUpdate_=this.onValueUpdate_.bind(this),this.element=t.createElement("div"),this.element.classList.add(cs()),e.viewProps.bindClassModifiers(this.element),this.formatter_=e.formatter,this.minValue_=e.minValue,this.maxValue_=e.maxValue,this.cursor_=e.cursor,this.cursor_.emitter.on("change",this.onCursorChange_);const n=t.createElementNS(D,"svg");n.classList.add(cs("g")),n.style.height=`calc(var(--bld-us) * ${e.lineCount})`,this.element.appendChild(n),this.svgElem_=n;const i=t.createElementNS(D,"polyline");this.svgElem_.appendChild(i),this.lineElem_=i;const s=t.createElement("div");s.classList.add(cs("t"),v("tt")()),this.element.appendChild(s),this.tooltipElem_=s,e.value.emitter.on("change",this.onValueUpdate_),this.value=e.value,this.update_()}get graphElement(){return this.svgElem_}update_(){const t=this.svgElem_.getBoundingClientRect(),e=this.value.rawValue.length-1,n=this.minValue_,i=this.maxValue_,s=[];this.value.rawValue.forEach(((o,r)=>{if(void 0===o)return;const a=Fe(r,0,e,0,t.width),l=Fe(o,n,i,t.height,0);s.push([a,l].join(","))})),this.lineElem_.setAttributeNS(null,"points",s.join(" "));const o=this.tooltipElem_,r=this.value.rawValue[this.cursor_.index];if(void 0===r)return void o.classList.remove(cs("t","a"));const a=Fe(this.cursor_.index,0,e,0,t.width),l=Fe(r,n,i,t.height,0);o.style.left=`${a}px`,o.style.top=`${l}px`,o.textContent=`${this.formatter_(r)}`,o.classList.contains(cs("t","a"))||(o.classList.add(cs("t","a"),cs("t","in")),j(o),o.classList.remove(cs("t","in")))}onValueUpdate_(){this.update_()}onCursorChange_(){this.update_()}}class us{constructor(t,e){if(this.onGraphMouseMove_=this.onGraphMouseMove_.bind(this),this.onGraphMouseLeave_=this.onGraphMouseLeave_.bind(this),this.onGraphPointerDown_=this.onGraphPointerDown_.bind(this),this.onGraphPointerMove_=this.onGraphPointerMove_.bind(this),this.onGraphPointerUp_=this.onGraphPointerUp_.bind(this),this.value=e.value,this.viewProps=e.viewProps,this.cursor_=new ds,this.view=new hs(t,{cursor:this.cursor_,formatter:e.formatter,lineCount:e.lineCount,maxValue:e.maxValue,minValue:e.minValue,value:this.value,viewProps:this.viewProps}),B(t)){const t=new Re(this.view.element);t.emitter.on("down",this.onGraphPointerDown_),t.emitter.on("move",this.onGraphPointerMove_),t.emitter.on("up",this.onGraphPointerUp_)}else this.view.element.addEventListener("mousemove",this.onGraphMouseMove_),this.view.element.addEventListener("mouseleave",this.onGraphMouseLeave_)}onGraphMouseLeave_(){this.cursor_.index=-1}onGraphMouseMove_(t){const e=this.view.element.getBoundingClientRect();this.cursor_.index=Math.floor(Fe(t.offsetX,0,e.width,0,this.value.rawValue.length))}onGraphPointerDown_(t){this.onGraphPointerMove_(t)}onGraphPointerMove_(t){t.data.point?this.cursor_.index=Math.floor(Fe(t.data.point.x,0,t.data.bounds.width,0,this.value.rawValue.length)):this.cursor_.index=-1}onGraphPointerUp_(){this.cursor_.index=-1}}function vs(t){return"format"in t&&!r(t.format)?t.format:Ce(2)}function ms(t){return"view"in t&&"graph"===t.view}const bs={id:"monitor-number",type:"monitor",accept:(t,e)=>{if("number"!=typeof t)return null;const n=M,i=L(e,{format:n.optional.function,lineCount:n.optional.number,max:n.optional.number,min:n.optional.number,view:n.optional.string});return i?{initialValue:t,params:i}:null},binding:{defaultBufferSize:t=>ms(t)?64:1,reader:t=>xe},controller:t=>ms(t.params)?function(t){var e,n,i;return new us(t.document,{formatter:vs(t.params),lineCount:null!==(e=t.params.lineCount)&&void 0!==e?e:ns.defaultLineCount,maxValue:null!==(n="max"in t.params?t.params.max:null)&&void 0!==n?n:100,minValue:null!==(i="min"in t.params?t.params.min:null)&&void 0!==i?i:0,value:t.value,viewProps:t.viewProps})}(t):function(t){var e;return 1===t.value.rawValue.length?new ls(t.document,{formatter:vs(t.params),value:t.value,viewProps:t.viewProps}):new os(t.document,{formatter:vs(t.params),lineCount:null!==(e=t.params.lineCount)&&void 0!==e?e:ns.defaultLineCount,value:t.value,viewProps:t.viewProps})}(t)},gs={id:"monitor-string",type:"monitor",accept:(t,e)=>{if("string"!=typeof t)return null;const n=M,i=L(e,{lineCount:n.optional.number,multiline:n.optional.boolean});return i?{initialValue:t,params:i}:null},binding:{reader:t=>ke},controller:t=>{var e;const n=t.value;return n.rawValue.length>1||"multiline"in t.params&&t.params.multiline?new os(t.document,{formatter:Ve,lineCount:null!==(e=t.params.lineCount)&&void 0!==e?e:ns.defaultLineCount,value:n,viewProps:t.viewProps}):new ls(t.document,{formatter:Ve,value:n,viewProps:t.viewProps})}};class _s{constructor(t){this.onValueChange_=this.onValueChange_.bind(this),this.reader=t.reader,this.writer=t.writer,this.emitter=new h,this.value=t.value,this.value.emitter.on("change",this.onValueChange_),this.target=t.target,this.read()}read(){const t=this.target.read();void 0!==t&&(this.value.rawValue=this.reader(t))}write_(t){this.writer(this.target,t)}onValueChange_(t){this.write_(t.rawValue),this.emitter.emit("change",{options:t.options,rawValue:t.rawValue,sender:this})}}class fs{constructor(t){this.onTick_=this.onTick_.bind(this),this.reader_=t.reader,this.target=t.target,this.emitter=new h,this.value=t.value,this.ticker=t.ticker,this.ticker.emitter.on("tick",this.onTick_),this.read()}dispose(){this.ticker.dispose()}read(){const t=this.target.read();if(void 0===t)return;const e=this.value.rawValue,n=this.reader_(t);this.value.rawValue=function(t,e){const n=[...Le(t),e];return n.length>t.length?n.splice(0,n.length-t.length):Se(n,t.length),n}(e,n),this.emitter.emit("update",{rawValue:n,sender:this})}onTick_(t){this.read()}}function ws(t,e){return 0===e?new Ut:new Ot(t,null!=e?e:ns.defaultInterval)}class xs{constructor(){this.pluginsMap_={blades:[],inputs:[],monitors:[]}}getAll(){return[...this.pluginsMap_.blades,...this.pluginsMap_.inputs,...this.pluginsMap_.monitors]}register(t){"blade"===t.type?this.pluginsMap_.blades.unshift(t):"input"===t.type?this.pluginsMap_.inputs.unshift(t):"monitor"===t.type&&this.pluginsMap_.monitors.unshift(t)}createInput(t,e,n){if(r(e.read()))throw new p({context:{key:e.key},type:"nomatchingcontroller"});const i=this.pluginsMap_.inputs.reduce(((i,s)=>i||function(t,e){const n=t.accept(e.target.read(),e.params);if(r(n))return null;const i=M,s={target:e.target,initialValue:n.initialValue,params:n.params},o=t.binding.reader(s),a=t.binding.constraint?t.binding.constraint(s):void 0,l=E(o(n.initialValue),{constraint:a,equals:t.binding.equals}),p=new _s({reader:o,target:e.target,value:l,writer:t.binding.writer(s)}),d=i.optional.boolean(e.params.disabled).value,c=i.optional.boolean(e.params.hidden).value,h=t.controller({constraint:a,document:e.document,initialValue:n.initialValue,params:n.params,value:p.value,viewProps:St.create({disabled:d,hidden:c})}),u=i.optional.string(e.params.label).value;return new nt(e.document,{binding:p,blade:W(),props:k.fromObject({label:u||e.target.key}),valueController:h})}(s,{document:t,target:e,params:n})),null);if(i)return i;throw new p({context:{key:e.key},type:"nomatchingcontroller"})}createMonitor(t,e,n){const i=this.pluginsMap_.monitors.reduce(((i,s)=>i||function(t,e){var n,i,s;const o=M,a=t.accept(e.target.read(),e.params);if(r(a))return null;const l={target:e.target,initialValue:a.initialValue,params:a.params},p=t.binding.reader(l),d=null!==(i=null!==(n=o.optional.number(e.params.bufferSize).value)&&void 0!==n?n:t.binding.defaultBufferSize&&t.binding.defaultBufferSize(a.params))&&void 0!==i?i:1,c=o.optional.number(e.params.interval).value,h=new fs({reader:p,target:e.target,ticker:ws(e.document,c),value:Me(d)}),u=o.optional.boolean(e.params.disabled).value,v=o.optional.boolean(e.params.hidden).value,m=t.controller({document:e.document,params:a.params,value:h.value,viewProps:St.create({disabled:u,hidden:v})}),b=null!==(s=o.optional.string(e.params.label).value)&&void 0!==s?s:e.target.key;return new st(e.document,{binding:h,blade:W(),props:k.fromObject({label:b}),valueController:m})}(s,{document:t,params:n,target:e})),null);if(i)return i;throw new p({context:{key:e.key},type:"nomatchingcontroller"})}createBlade(t,e){const n=this.pluginsMap_.blades.reduce(((n,i)=>n||function(t,e){const n=t.accept(e.params);if(!n)return null;const i=M.optional.boolean(e.params.disabled).value,s=M.optional.boolean(e.params.hidden).value;return t.controller({blade:W(),document:e.document,params:Object.assign(Object.assign({},n.params),{disabled:i,hidden:s}),viewProps:St.create({disabled:i,hidden:s})})}(i,{document:t,params:e})),null);if(!n)throw new p({type:"nomatchingview",context:{params:e}});return n}createBladeApi(t){if(t instanceof nt)return new et(t);if(t instanceof st)return new it(t);if(t instanceof mt)return new lt(t,this);const e=this.pluginsMap_.blades.reduce(((e,n)=>e||n.api({controller:t,pool:this})),null);if(!e)throw p.shouldNeverHappen();return e}}class ys extends e{constructor(t){super(t),this.emitter_=new h,this.controller_.valueController.value.emitter.on("change",(t=>{this.emitter_.emit("change",{event:new i(this,t.rawValue)})}))}get label(){return this.controller_.props.get("label")}set label(t){this.controller_.props.set("label",t)}get options(){return this.controller_.valueController.props.get("options")}set options(t){this.controller_.valueController.props.set("options",t)}get value(){return this.controller_.valueController.value.rawValue}set value(t){this.controller_.valueController.value.rawValue=t}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}}class Cs extends e{constructor(t){super(t),this.emitter_=new h,this.controller_.valueController.value.emitter.on("change",(t=>{this.emitter_.emit("change",{event:new i(this,t.rawValue)})}))}get label(){return this.controller_.props.get("label")}set label(t){this.controller_.props.set("label",t)}get maxValue(){return this.controller_.valueController.sliderController.props.get("maxValue")}set maxValue(t){this.controller_.valueController.sliderController.props.set("maxValue",t)}get minValue(){return this.controller_.valueController.sliderController.props.get("minValue")}set minValue(t){this.controller_.valueController.sliderController.props.set("minValue",t)}get value(){return this.controller_.valueController.value.rawValue}set value(t){this.controller_.valueController.value.rawValue=t}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}}class Ps extends e{constructor(t){super(t),this.emitter_=new h,this.controller_.valueController.value.emitter.on("change",(t=>{this.emitter_.emit("change",{event:new i(this,t.rawValue)})}))}get label(){return this.controller_.props.get("label")}set label(t){this.controller_.props.set("label",t)}get formatter(){return this.controller_.valueController.props.get("formatter")}set formatter(t){this.controller_.valueController.props.set("formatter",t)}get value(){return this.controller_.valueController.value.rawValue}set value(t){this.controller_.valueController.value.rawValue=t}on(t,e){const n=e.bind(this);return this.emitter_.on(t,(t=>{n(t.event)})),this}}const Es={id:"list",type:"blade",accept(t){const e=M,n=L(t,{options:e.required.custom(Je),value:e.required.raw,view:e.required.constant("list"),label:e.optional.string});return n?{params:n}:null},controller(t){const e=new Yt(t.document,{props:k.fromObject({options:en(t.params.options)}),value:E(t.params.value),viewProps:t.viewProps});return new wt(t.document,{blade:t.blade,props:k.fromObject({label:t.params.label}),valueController:e})},api:t=>t.controller instanceof wt&&t.controller.valueController instanceof Yt?new ys(t.controller):null};class ks extends pt{constructor(t,e){super(t,e)}get element(){return this.controller_.view.element}importPreset(t){(function(t,e){t.forEach((t=>{const n=e[t.presetKey];void 0!==n&&t.write(n)}))})(this.controller_.rackController.rack.find(nt).map((t=>t.binding.target)),t),this.refresh()}exportPreset(){return this.controller_.rackController.rack.find(nt).map((t=>t.binding.target)).reduce(((t,e)=>Object.assign(t,{[e.presetKey]:e.read()})),{})}refresh(){this.controller_.rackController.rack.find(nt).forEach((t=>{t.binding.read()})),this.controller_.rackController.rack.find(st).forEach((t=>{t.binding.read()}))}}class Vs extends _t{constructor(t,e){super(t,{expanded:e.expanded,blade:e.blade,props:e.props,root:!0,viewProps:e.viewProps})}}const Ss={id:"slider",type:"blade",accept(t){const e=M,n=L(t,{max:e.required.number,min:e.required.number,view:e.required.constant("slider"),format:e.optional.function,label:e.optional.string,value:e.optional.number});return n?{params:n}:null},controller(t){var e,n;const i=null!==(e=t.params.value)&&void 0!==e?e:0,s=new Xe(t.document,{baseStep:1,parser:we,sliderProps:k.fromObject({maxValue:t.params.max,minValue:t.params.min}),textProps:k.fromObject({draggingScale:an(void 0,i),formatter:null!==(n=t.params.format)&&void 0!==n?n:ye}),value:E(i),viewProps:t.viewProps});return new wt(t.document,{blade:t.blade,props:k.fromObject({label:t.params.label}),valueController:s})},api:t=>t.controller instanceof wt&&t.controller.valueController instanceof Xe?new Cs(t.controller):null},Ms={id:"text",type:"blade",accept(t){const e=M,n=L(t,{parse:e.required.function,value:e.required.raw,view:e.required.constant("text"),format:e.optional.function,label:e.optional.string});return n?{params:n}:null},controller(t){var e;const n=new te(t.document,{parser:t.params.parse,props:k.fromObject({formatter:null!==(e=t.params.format)&&void 0!==e?e:t=>String(t)}),value:E(t.params.value),viewProps:t.viewProps});return new wt(t.document,{blade:t.blade,props:k.fromObject({label:t.params.label}),valueController:n})},api:t=>t.controller instanceof wt&&t.controller.valueController instanceof te?new Ps(t.controller):null};function Ls(t,e,n){if(t.querySelector(`style[data-tp-style=${e}]`))return;const i=t.createElement("style");i.dataset.tpStyle=e,i.textContent=n,t.head.appendChild(i)}const As=new class{constructor(t){const[e,n]=t.split("-"),i=e.split(".");this.major=parseInt(i[0],10),this.minor=parseInt(i[1],10),this.patch=parseInt(i[2],10),this.prerelease=null!=n?n:null}toString(){const t=[this.major,this.minor,this.patch].join(".");return null!==this.prerelease?[t,this.prerelease].join("-"):t}}("3.0.7");t.BladeApi=e,t.ButtonApi=c,t.FolderApi=pt,t.InputBindingApi=et,t.ListApi=ys,t.MonitorBindingApi=it,t.Pane=class extends ks{constructor(t){var e;const n=t||{},i=null!==(e=n.document)&&void 0!==e?e:R(),s=function(){const t=new xs;return[Ki,Yi,ts,es,Pi,gi,bi,mi,cn,ps,gs,bs,G,ft,Et,Ft].forEach((e=>{t.register(e)})),t}();super(new Vs(i,{expanded:n.expanded,blade:W(),props:k.fromObject({title:n.title}),viewProps:St.create()}),s),this.pool_=s,this.containerElem_=n.container||function(t){const e=t.createElement("div");return e.classList.add(v("dfw")()),t.body&&t.body.appendChild(e),e}(i),this.containerElem_.appendChild(this.element),this.doc_=i,this.usesDefaultWrapper_=!n.container,this.setUpDefaultPlugins_()}get document(){if(!this.doc_)throw p.alreadyDisposed();return this.doc_}dispose(){const t=this.containerElem_;if(!t)throw p.alreadyDisposed();if(this.usesDefaultWrapper_){const e=t.parentElement;e&&e.removeChild(t)}this.containerElem_=null,this.doc_=null,super.dispose()}registerPlugin(t){("plugin"in t?[t.plugin]:"plugins"in t?t.plugins:[]).forEach((t=>{this.pool_.register(t),this.embedPluginStyle_(t)}))}embedPluginStyle_(t){t.css&&Ls(this.document,`plugin-${t.id}`,t.css)}setUpDefaultPlugins_(){Ls(this.document,"default",".tp-lstv_s,.tp-btnv_b,.tp-p2dv_b,.tp-colswv_sw,.tp-p2dpv_p,.tp-txtv_i,.tp-grlv_g,.tp-sglv_i,.tp-mllv_i,.tp-fldv_b,.tp-rotv_b,.tp-ckbv_i,.tp-coltxtv_ms,.tp-tbiv_b{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border-width:0;font-family:inherit;font-size:inherit;font-weight:inherit;margin:0;outline:none;padding:0}.tp-lstv_s,.tp-btnv_b,.tp-p2dv_b{background-color:var(--btn-bg);border-radius:var(--elm-br);color:var(--btn-fg);cursor:pointer;display:block;font-weight:bold;height:var(--bld-us);line-height:var(--bld-us);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tp-lstv_s:hover,.tp-btnv_b:hover,.tp-p2dv_b:hover{background-color:var(--btn-bg-h)}.tp-lstv_s:focus,.tp-btnv_b:focus,.tp-p2dv_b:focus{background-color:var(--btn-bg-f)}.tp-lstv_s:active,.tp-btnv_b:active,.tp-p2dv_b:active{background-color:var(--btn-bg-a)}.tp-lstv_s:disabled,.tp-btnv_b:disabled,.tp-p2dv_b:disabled{opacity:0.5}.tp-colswv_sw,.tp-p2dpv_p,.tp-txtv_i{background-color:var(--in-bg);border-radius:var(--elm-br);box-sizing:border-box;color:var(--in-fg);font-family:inherit;height:var(--bld-us);line-height:var(--bld-us);min-width:0;width:100%}.tp-colswv_sw:hover,.tp-p2dpv_p:hover,.tp-txtv_i:hover{background-color:var(--in-bg-h)}.tp-colswv_sw:focus,.tp-p2dpv_p:focus,.tp-txtv_i:focus{background-color:var(--in-bg-f)}.tp-colswv_sw:active,.tp-p2dpv_p:active,.tp-txtv_i:active{background-color:var(--in-bg-a)}.tp-colswv_sw:disabled,.tp-p2dpv_p:disabled,.tp-txtv_i:disabled{opacity:0.5}.tp-grlv_g,.tp-sglv_i,.tp-mllv_i{background-color:var(--mo-bg);border-radius:var(--elm-br);box-sizing:border-box;color:var(--mo-fg);height:var(--bld-us);width:100%}.tp-rotv{--font-family: var(--tp-font-family, Roboto Mono,Source Code Pro,Menlo,Courier,monospace);--bs-br: var(--tp-base-border-radius, 6px);--cnt-h-p: var(--tp-container-horizontal-padding, 4px);--cnt-v-p: var(--tp-container-vertical-padding, 4px);--elm-br: var(--tp-element-border-radius, 2px);--bld-s: var(--tp-blade-spacing, 4px);--bld-us: var(--tp-blade-unit-size, 20px);--bs-bg: var(--tp-base-background-color, #2f3137);--bs-sh: var(--tp-base-shadow-color, rgba(0,0,0,0.2));--btn-bg: var(--tp-button-background-color, #adafb8);--btn-bg-a: var(--tp-button-background-color-active, #d6d7db);--btn-bg-f: var(--tp-button-background-color-focus, #c8cad0);--btn-bg-h: var(--tp-button-background-color-hover, #bbbcc4);--btn-fg: var(--tp-button-foreground-color, #2f3137);--cnt-bg: var(--tp-container-background-color, rgba(187,188,196,0.1));--cnt-bg-a: var(--tp-container-background-color-active, rgba(187,188,196,0.25));--cnt-bg-f: var(--tp-container-background-color-focus, rgba(187,188,196,0.2));--cnt-bg-h: var(--tp-container-background-color-hover, rgba(187,188,196,0.15));--cnt-fg: var(--tp-container-foreground-color, #bbbcc4);--in-bg: var(--tp-input-background-color, rgba(187,188,196,0.1));--in-bg-a: var(--tp-input-background-color-active, rgba(187,188,196,0.25));--in-bg-f: var(--tp-input-background-color-focus, rgba(187,188,196,0.2));--in-bg-h: var(--tp-input-background-color-hover, rgba(187,188,196,0.15));--in-fg: var(--tp-input-foreground-color, #bbbcc4);--lbl-fg: var(--tp-label-foreground-color, rgba(187,188,196,0.7));--mo-bg: var(--tp-monitor-background-color, rgba(0,0,0,0.2));--mo-fg: var(--tp-monitor-foreground-color, rgba(187,188,196,0.7));--grv-fg: var(--tp-groove-foreground-color, rgba(0,0,0,0.2))}.tp-fldv_c>.tp-cntv.tp-v-lst,.tp-tabv_c .tp-brkv>.tp-cntv.tp-v-lst,.tp-rotv_c>.tp-cntv.tp-v-lst{margin-bottom:calc(-1 * var(--cnt-v-p))}.tp-fldv_c>.tp-fldv.tp-v-lst .tp-fldv_c,.tp-tabv_c .tp-brkv>.tp-fldv.tp-v-lst .tp-fldv_c,.tp-rotv_c>.tp-fldv.tp-v-lst .tp-fldv_c{border-bottom-left-radius:0}.tp-fldv_c>.tp-fldv.tp-v-lst .tp-fldv_b,.tp-tabv_c .tp-brkv>.tp-fldv.tp-v-lst .tp-fldv_b,.tp-rotv_c>.tp-fldv.tp-v-lst .tp-fldv_b{border-bottom-left-radius:0}.tp-fldv_c>*:not(.tp-v-fst),.tp-tabv_c .tp-brkv>*:not(.tp-v-fst),.tp-rotv_c>*:not(.tp-v-fst){margin-top:var(--bld-s)}.tp-fldv_c>.tp-sprv:not(.tp-v-fst),.tp-tabv_c .tp-brkv>.tp-sprv:not(.tp-v-fst),.tp-rotv_c>.tp-sprv:not(.tp-v-fst),.tp-fldv_c>.tp-cntv:not(.tp-v-fst),.tp-tabv_c .tp-brkv>.tp-cntv:not(.tp-v-fst),.tp-rotv_c>.tp-cntv:not(.tp-v-fst){margin-top:var(--cnt-v-p)}.tp-fldv_c>.tp-sprv+*:not(.tp-v-hidden),.tp-tabv_c .tp-brkv>.tp-sprv+*:not(.tp-v-hidden),.tp-rotv_c>.tp-sprv+*:not(.tp-v-hidden),.tp-fldv_c>.tp-cntv+*:not(.tp-v-hidden),.tp-tabv_c .tp-brkv>.tp-cntv+*:not(.tp-v-hidden),.tp-rotv_c>.tp-cntv+*:not(.tp-v-hidden){margin-top:var(--cnt-v-p)}.tp-fldv_c>.tp-sprv:not(.tp-v-hidden)+.tp-sprv,.tp-tabv_c .tp-brkv>.tp-sprv:not(.tp-v-hidden)+.tp-sprv,.tp-rotv_c>.tp-sprv:not(.tp-v-hidden)+.tp-sprv,.tp-fldv_c>.tp-cntv:not(.tp-v-hidden)+.tp-cntv,.tp-tabv_c .tp-brkv>.tp-cntv:not(.tp-v-hidden)+.tp-cntv,.tp-rotv_c>.tp-cntv:not(.tp-v-hidden)+.tp-cntv{margin-top:0}.tp-fldv_c>.tp-cntv,.tp-tabv_c .tp-brkv>.tp-cntv{margin-left:4px}.tp-fldv_c>.tp-fldv>.tp-fldv_b,.tp-tabv_c .tp-brkv>.tp-fldv>.tp-fldv_b{border-top-left-radius:var(--elm-br);border-bottom-left-radius:var(--elm-br)}.tp-fldv_c>.tp-fldv.tp-fldv-expanded>.tp-fldv_b,.tp-tabv_c .tp-brkv>.tp-fldv.tp-fldv-expanded>.tp-fldv_b{border-bottom-left-radius:0}.tp-fldv_c .tp-fldv>.tp-fldv_c,.tp-tabv_c .tp-brkv .tp-fldv>.tp-fldv_c{border-bottom-left-radius:var(--elm-br)}.tp-fldv_c>.tp-tabv>.tp-tabv_i,.tp-tabv_c .tp-brkv>.tp-tabv>.tp-tabv_i{border-top-left-radius:var(--elm-br)}.tp-fldv_c .tp-tabv>.tp-tabv_c,.tp-tabv_c .tp-brkv .tp-tabv>.tp-tabv_c{border-bottom-left-radius:var(--elm-br)}.tp-fldv_b,.tp-rotv_b{background-color:var(--cnt-bg);color:var(--cnt-fg);cursor:pointer;display:block;height:calc(var(--bld-us) + 4px);line-height:calc(var(--bld-us) + 4px);overflow:hidden;padding-left:var(--cnt-h-p);padding-right:calc(2px * 2 + var(--bld-us) + var(--cnt-h-p));position:relative;text-align:left;text-overflow:ellipsis;white-space:nowrap;width:100%;transition:border-radius .2s ease-in-out .2s}.tp-fldv_b:hover,.tp-rotv_b:hover{background-color:var(--cnt-bg-h)}.tp-fldv_b:focus,.tp-rotv_b:focus{background-color:var(--cnt-bg-f)}.tp-fldv_b:active,.tp-rotv_b:active{background-color:var(--cnt-bg-a)}.tp-fldv_b:disabled,.tp-rotv_b:disabled{opacity:0.5}.tp-fldv_m,.tp-rotv_m{background:linear-gradient(to left, var(--cnt-fg), var(--cnt-fg) 2px, transparent 2px, transparent 4px, var(--cnt-fg) 4px);border-radius:2px;bottom:0;content:'';display:block;height:6px;right:calc(var(--cnt-h-p) + (var(--bld-us) + 4px - 6px) / 2 - 2px);margin:auto;opacity:0.5;position:absolute;top:0;transform:rotate(90deg);transition:transform .2s ease-in-out;width:6px}.tp-fldv.tp-fldv-expanded>.tp-fldv_b>.tp-fldv_m,.tp-rotv.tp-rotv-expanded .tp-rotv_m{transform:none}.tp-fldv_c,.tp-rotv_c{box-sizing:border-box;height:0;opacity:0;overflow:hidden;padding-bottom:0;padding-top:0;position:relative;transition:height .2s ease-in-out,opacity .2s linear,padding .2s ease-in-out}.tp-fldv.tp-fldv-cpl:not(.tp-fldv-expanded)>.tp-fldv_c,.tp-rotv.tp-rotv-cpl:not(.tp-rotv-expanded) .tp-rotv_c{display:none}.tp-fldv.tp-fldv-expanded>.tp-fldv_c,.tp-rotv.tp-rotv-expanded .tp-rotv_c{opacity:1;padding-bottom:var(--cnt-v-p);padding-top:var(--cnt-v-p);transform:none;overflow:visible;transition:height .2s ease-in-out,opacity .2s linear .2s,padding .2s ease-in-out}.tp-coltxtv_m,.tp-lstv{position:relative}.tp-lstv_s{padding:0 20px 0 4px;width:100%}.tp-coltxtv_mm,.tp-lstv_m{bottom:0;margin:auto;pointer-events:none;position:absolute;right:2px;top:0}.tp-coltxtv_mm svg,.tp-lstv_m svg{bottom:0;height:16px;margin:auto;position:absolute;right:0;top:0;width:16px}.tp-coltxtv_mm svg path,.tp-lstv_m svg path{fill:currentColor}.tp-coltxtv_w,.tp-pndtxtv{display:flex}.tp-coltxtv_c,.tp-pndtxtv_a{width:100%}.tp-coltxtv_c+.tp-coltxtv_c,.tp-pndtxtv_a+.tp-coltxtv_c,.tp-coltxtv_c+.tp-pndtxtv_a,.tp-pndtxtv_a+.tp-pndtxtv_a{margin-left:2px}.tp-btnv_b{width:100%}.tp-btnv_t{text-align:center}.tp-ckbv_l{display:block;position:relative}.tp-ckbv_i{left:0;opacity:0;position:absolute;top:0}.tp-ckbv_w{background-color:var(--in-bg);border-radius:var(--elm-br);cursor:pointer;display:block;height:var(--bld-us);position:relative;width:var(--bld-us)}.tp-ckbv_w svg{bottom:0;display:block;height:16px;left:0;margin:auto;opacity:0;position:absolute;right:0;top:0;width:16px}.tp-ckbv_w svg path{fill:none;stroke:var(--in-fg);stroke-width:2}.tp-ckbv_i:hover+.tp-ckbv_w{background-color:var(--in-bg-h)}.tp-ckbv_i:focus+.tp-ckbv_w{background-color:var(--in-bg-f)}.tp-ckbv_i:active+.tp-ckbv_w{background-color:var(--in-bg-a)}.tp-ckbv_i:checked+.tp-ckbv_w svg{opacity:1}.tp-ckbv.tp-v-disabled .tp-ckbv_w{opacity:0.5}.tp-colv{position:relative}.tp-colv_h{display:flex}.tp-colv_s{flex-grow:0;flex-shrink:0;width:var(--bld-us)}.tp-colv_t{flex:1;margin-left:4px}.tp-colv_p{height:0;margin-top:0;opacity:0;overflow:hidden;transition:height .2s ease-in-out,opacity .2s linear,margin .2s ease-in-out}.tp-colv.tp-colv-cpl .tp-colv_p{overflow:visible}.tp-colv.tp-colv-expanded .tp-colv_p{margin-top:var(--bld-s);opacity:1}.tp-colv .tp-popv{left:calc(-1 * var(--cnt-h-p));right:calc(-1 * var(--cnt-h-p));top:var(--bld-us)}.tp-colpv_h,.tp-colpv_ap{margin-left:6px;margin-right:6px}.tp-colpv_h{margin-top:var(--bld-s)}.tp-colpv_rgb{display:flex;margin-top:var(--bld-s);width:100%}.tp-colpv_a{display:flex;margin-top:var(--cnt-v-p);padding-top:calc(var(--cnt-v-p) + 2px);position:relative}.tp-colpv_a:before{background-color:var(--grv-fg);content:'';height:2px;left:calc(-1 * var(--cnt-h-p));position:absolute;right:calc(-1 * var(--cnt-h-p));top:0}.tp-colpv_ap{align-items:center;display:flex;flex:3}.tp-colpv_at{flex:1;margin-left:4px}.tp-svpv{border-radius:var(--elm-br);outline:none;overflow:hidden;position:relative}.tp-svpv_c{cursor:crosshair;display:block;height:calc(var(--bld-us) * 4);width:100%}.tp-svpv_m{border-radius:100%;border:rgba(255,255,255,0.75) solid 2px;box-sizing:border-box;filter:drop-shadow(0 0 1px rgba(0,0,0,0.3));height:12px;margin-left:-6px;margin-top:-6px;pointer-events:none;position:absolute;width:12px}.tp-svpv:focus .tp-svpv_m{border-color:#fff}.tp-hplv{cursor:pointer;height:var(--bld-us);outline:none;position:relative}.tp-hplv_c{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAABCAYAAABubagXAAAAQ0lEQVQoU2P8z8Dwn0GCgQEDi2OK/RBgYHjBgIpfovFh8j8YBIgzFGQxuqEgPhaDOT5gOhPkdCxOZeBg+IDFZZiGAgCaSSMYtcRHLgAAAABJRU5ErkJggg==);background-position:left top;background-repeat:no-repeat;background-size:100% 100%;border-radius:2px;display:block;height:4px;left:0;margin-top:-2px;position:absolute;top:50%;width:100%}.tp-hplv_m{border-radius:var(--elm-br);border:rgba(255,255,255,0.75) solid 2px;box-shadow:0 0 2px rgba(0,0,0,0.1);box-sizing:border-box;height:12px;left:50%;margin-left:-6px;margin-top:-6px;pointer-events:none;position:absolute;top:50%;width:12px}.tp-hplv:focus .tp-hplv_m{border-color:#fff}.tp-aplv{cursor:pointer;height:var(--bld-us);outline:none;position:relative;width:100%}.tp-aplv_b{background-color:#fff;background-image:linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%),linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%);background-size:4px 4px;background-position:0 0,2px 2px;border-radius:2px;display:block;height:4px;left:0;margin-top:-2px;overflow:hidden;position:absolute;top:50%;width:100%}.tp-aplv_c{bottom:0;left:0;position:absolute;right:0;top:0}.tp-aplv_m{background-color:#fff;background-image:linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%),linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%);background-size:12px 12px;background-position:0 0,6px 6px;border-radius:var(--elm-br);box-shadow:0 0 2px rgba(0,0,0,0.1);height:12px;left:50%;margin-left:-6px;margin-top:-6px;overflow:hidden;pointer-events:none;position:absolute;top:50%;width:12px}.tp-aplv_p{border-radius:var(--elm-br);border:rgba(255,255,255,0.75) solid 2px;box-sizing:border-box;bottom:0;left:0;position:absolute;right:0;top:0}.tp-aplv:focus .tp-aplv_p{border-color:#fff}.tp-colswv{background-color:#fff;background-image:linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%),linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%);background-size:10px 10px;background-position:0 0,5px 5px;border-radius:var(--elm-br)}.tp-colswv.tp-v-disabled{opacity:0.5}.tp-colswv_b{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border-width:0;cursor:pointer;display:block;height:var(--bld-us);left:0;margin:0;outline:none;padding:0;position:absolute;top:0;width:var(--bld-us)}.tp-colswv_b:focus::after{border:rgba(255,255,255,0.75) solid 2px;border-radius:var(--elm-br);bottom:0;content:'';display:block;left:0;position:absolute;right:0;top:0}.tp-coltxtv{display:flex;width:100%}.tp-coltxtv_m{margin-right:4px}.tp-coltxtv_ms{border-radius:var(--elm-br);color:var(--lbl-fg);cursor:pointer;height:var(--bld-us);line-height:var(--bld-us);padding:0 18px 0 4px}.tp-coltxtv_ms:hover{background-color:var(--in-bg-h)}.tp-coltxtv_ms:focus{background-color:var(--in-bg-f)}.tp-coltxtv_ms:active{background-color:var(--in-bg-a)}.tp-coltxtv_mm{color:var(--lbl-fg)}.tp-coltxtv_w{flex:1}.tp-dfwv{position:absolute;top:8px;right:8px;width:256px}.tp-fldv.tp-fldv-not .tp-fldv_b{display:none}.tp-fldv_t{padding-left:4px}.tp-fldv_c{border-left:var(--cnt-bg) solid 4px}.tp-fldv_b:hover+.tp-fldv_c{border-left-color:var(--cnt-bg-h)}.tp-fldv_b:focus+.tp-fldv_c{border-left-color:var(--cnt-bg-f)}.tp-fldv_b:active+.tp-fldv_c{border-left-color:var(--cnt-bg-a)}.tp-grlv{position:relative}.tp-grlv_g{display:block;height:calc(var(--bld-us) * 3)}.tp-grlv_g polyline{fill:none;stroke:var(--mo-fg);stroke-linejoin:round}.tp-grlv_t{margin-top:-4px;transition:left 0.05s, top 0.05s;visibility:hidden}.tp-grlv_t.tp-grlv_t-a{visibility:visible}.tp-grlv_t.tp-grlv_t-in{transition:none}.tp-grlv.tp-v-disabled .tp-grlv_g{opacity:0.5}.tp-grlv .tp-ttv{background-color:var(--mo-fg)}.tp-grlv .tp-ttv::before{border-top-color:var(--mo-fg)}.tp-lblv{align-items:center;display:flex;line-height:1.3;padding-left:var(--cnt-h-p);padding-right:var(--cnt-h-p)}.tp-lblv.tp-lblv-nol{display:block}.tp-lblv_l{color:var(--lbl-fg);flex:1;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;overflow:hidden;padding-left:4px;padding-right:16px}.tp-lblv.tp-v-disabled .tp-lblv_l{opacity:0.5}.tp-lblv.tp-lblv-nol .tp-lblv_l{display:none}.tp-lblv_v{align-self:flex-start;flex-grow:0;flex-shrink:0;width:160px}.tp-lblv.tp-lblv-nol .tp-lblv_v{width:100%}.tp-lstv_s{padding:0 20px 0 4px;width:100%}.tp-lstv_m{color:var(--btn-fg)}.tp-sglv_i{padding:0 4px}.tp-sglv.tp-v-disabled .tp-sglv_i{opacity:0.5}.tp-mllv_i{display:block;height:calc(var(--bld-us) * 3);line-height:var(--bld-us);padding:0 4px;resize:none;white-space:pre}.tp-mllv.tp-v-disabled .tp-mllv_i{opacity:0.5}.tp-p2dv{position:relative}.tp-p2dv_h{display:flex}.tp-p2dv_b{height:var(--bld-us);margin-right:4px;position:relative;width:var(--bld-us)}.tp-p2dv_b svg{display:block;height:16px;left:50%;margin-left:-8px;margin-top:-8px;position:absolute;top:50%;width:16px}.tp-p2dv_b svg path{stroke:currentColor;stroke-width:2}.tp-p2dv_b svg circle{fill:currentColor}.tp-p2dv_t{flex:1}.tp-p2dv_p{height:0;margin-top:0;opacity:0;overflow:hidden;transition:height .2s ease-in-out,opacity .2s linear,margin .2s ease-in-out}.tp-p2dv.tp-p2dv-expanded .tp-p2dv_p{margin-top:var(--bld-s);opacity:1}.tp-p2dv .tp-popv{left:calc(-1 * var(--cnt-h-p));right:calc(-1 * var(--cnt-h-p));top:var(--bld-us)}.tp-p2dpv{padding-left:calc(var(--bld-us) + 4px)}.tp-p2dpv_p{cursor:crosshair;height:0;overflow:hidden;padding-bottom:100%;position:relative}.tp-p2dpv_g{display:block;height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%}.tp-p2dpv_ax{opacity:0.1;stroke:var(--in-fg);stroke-dasharray:1}.tp-p2dpv_l{opacity:0.5;stroke:var(--in-fg);stroke-dasharray:1}.tp-p2dpv_m{border:var(--in-fg) solid 1px;border-radius:50%;box-sizing:border-box;height:4px;margin-left:-2px;margin-top:-2px;position:absolute;width:4px}.tp-p2dpv_p:focus .tp-p2dpv_m{background-color:var(--in-fg);border-width:0}.tp-popv{background-color:var(--bs-bg);border-radius:6px;box-shadow:0 2px 4px var(--bs-sh);display:none;max-width:168px;padding:var(--cnt-v-p) var(--cnt-h-p);position:absolute;visibility:hidden;z-index:1000}.tp-popv.tp-popv-v{display:block;visibility:visible}.tp-sprv_r{background-color:var(--grv-fg);border-width:0;display:block;height:2px;margin:0;width:100%}.tp-sldv.tp-v-disabled{opacity:0.5}.tp-sldv_t{box-sizing:border-box;cursor:pointer;height:var(--bld-us);margin:0 6px;outline:none;position:relative}.tp-sldv_t::before{background-color:var(--in-bg);border-radius:1px;bottom:0;content:'';display:block;height:2px;left:0;margin:auto;position:absolute;right:0;top:0}.tp-sldv_k{height:100%;left:0;position:absolute;top:0}.tp-sldv_k::before{background-color:var(--in-fg);border-radius:1px;bottom:0;content:'';display:block;height:2px;left:0;margin-bottom:auto;margin-top:auto;position:absolute;right:0;top:0}.tp-sldv_k::after{background-color:var(--btn-bg);border-radius:var(--elm-br);bottom:0;content:'';display:block;height:12px;margin-bottom:auto;margin-top:auto;position:absolute;right:-6px;top:0;width:12px}.tp-sldv_t:hover .tp-sldv_k::after{background-color:var(--btn-bg-h)}.tp-sldv_t:focus .tp-sldv_k::after{background-color:var(--btn-bg-f)}.tp-sldv_t:active .tp-sldv_k::after{background-color:var(--btn-bg-a)}.tp-sldtxtv{display:flex}.tp-sldtxtv_s{flex:2}.tp-sldtxtv_t{flex:1;margin-left:4px}.tp-tabv.tp-v-disabled{opacity:0.5}.tp-tabv_i{align-items:flex-end;display:flex;overflow:hidden}.tp-tabv.tp-tabv-nop .tp-tabv_i{height:calc(var(--bld-us) + 4px);position:relative}.tp-tabv.tp-tabv-nop .tp-tabv_i::before{background-color:var(--cnt-bg);bottom:0;content:'';height:2px;left:0;position:absolute;right:0}.tp-tabv_c{border-left:var(--cnt-bg) solid 4px;padding-bottom:var(--cnt-v-p);padding-top:var(--cnt-v-p)}.tp-tbiv{flex:1;min-width:0;position:relative}.tp-tbiv+.tp-tbiv{margin-left:2px}.tp-tbiv+.tp-tbiv::before{background-color:var(--cnt-bg);bottom:0;content:'';height:2px;left:-2px;position:absolute;width:2px}.tp-tbiv_b{background-color:var(--cnt-bg);display:block;padding-left:calc(var(--cnt-h-p) + 4px);padding-right:calc(var(--cnt-h-p) + 4px);width:100%}.tp-tbiv_b:hover{background-color:var(--cnt-bg-h)}.tp-tbiv_b:focus{background-color:var(--cnt-bg-f)}.tp-tbiv_b:active{background-color:var(--cnt-bg-a)}.tp-tbiv_b:disabled{opacity:0.5}.tp-tbiv_t{color:var(--cnt-fg);height:calc(var(--bld-us) + 4px);line-height:calc(var(--bld-us) + 4px);opacity:0.5;overflow:hidden;text-overflow:ellipsis}.tp-tbiv.tp-tbiv-sel .tp-tbiv_t{opacity:1}.tp-txtv{position:relative}.tp-txtv_i{padding:0 4px}.tp-txtv.tp-txtv-fst .tp-txtv_i{border-bottom-right-radius:0;border-top-right-radius:0}.tp-txtv.tp-txtv-mid .tp-txtv_i{border-radius:0}.tp-txtv.tp-txtv-lst .tp-txtv_i{border-bottom-left-radius:0;border-top-left-radius:0}.tp-txtv.tp-txtv-num .tp-txtv_i{text-align:right}.tp-txtv.tp-txtv-drg .tp-txtv_i{opacity:0.3}.tp-txtv_k{cursor:pointer;height:100%;left:-3px;position:absolute;top:0;width:12px}.tp-txtv_k::before{background-color:var(--in-fg);border-radius:1px;bottom:0;content:'';height:calc(var(--bld-us) - 4px);left:50%;margin-bottom:auto;margin-left:-1px;margin-top:auto;opacity:0.1;position:absolute;top:0;transition:border-radius 0.1s, height 0.1s, transform 0.1s, width 0.1s;width:2px}.tp-txtv_k:hover::before,.tp-txtv.tp-txtv-drg .tp-txtv_k::before{opacity:1}.tp-txtv.tp-txtv-drg .tp-txtv_k::before{border-radius:50%;height:4px;transform:translateX(-1px);width:4px}.tp-txtv_g{bottom:0;display:block;height:8px;left:50%;margin:auto;overflow:visible;pointer-events:none;position:absolute;top:0;visibility:hidden;width:100%}.tp-txtv.tp-txtv-drg .tp-txtv_g{visibility:visible}.tp-txtv_gb{fill:none;stroke:var(--in-fg);stroke-dasharray:1}.tp-txtv_gh{fill:none;stroke:var(--in-fg)}.tp-txtv .tp-ttv{margin-left:6px;visibility:hidden}.tp-txtv.tp-txtv-drg .tp-ttv{visibility:visible}.tp-ttv{background-color:var(--in-fg);border-radius:var(--elm-br);color:var(--bs-bg);padding:2px 4px;pointer-events:none;position:absolute;transform:translate(-50%, -100%)}.tp-ttv::before{border-color:var(--in-fg) transparent transparent transparent;border-style:solid;border-width:2px;box-sizing:border-box;content:'';font-size:0.9em;height:4px;left:50%;margin-left:-2px;position:absolute;top:100%;width:4px}.tp-rotv{background-color:var(--bs-bg);border-radius:var(--bs-br);box-shadow:0 2px 4px var(--bs-sh);font-family:var(--font-family);font-size:11px;font-weight:500;line-height:1;text-align:left}.tp-rotv_b{border-bottom-left-radius:var(--bs-br);border-bottom-right-radius:var(--bs-br);border-top-left-radius:var(--bs-br);border-top-right-radius:var(--bs-br);padding-left:calc(2px * 2 + var(--bld-us) + var(--cnt-h-p));text-align:center}.tp-rotv.tp-rotv-expanded .tp-rotv_b{border-bottom-left-radius:0;border-bottom-right-radius:0}.tp-rotv.tp-rotv-not .tp-rotv_b{display:none}.tp-rotv_c>.tp-fldv.tp-v-lst>.tp-fldv_c,.tp-rotv_c>.tp-tabv.tp-v-lst>.tp-tabv_c{border-bottom-left-radius:var(--bs-br);border-bottom-right-radius:var(--bs-br)}.tp-rotv_c>.tp-fldv.tp-v-lst:not(.tp-fldv-expanded)>.tp-fldv_b{border-bottom-left-radius:var(--bs-br);border-bottom-right-radius:var(--bs-br)}.tp-rotv_c .tp-fldv.tp-v-vlst:not(.tp-fldv-expanded)>.tp-fldv_b{border-bottom-right-radius:var(--bs-br)}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-fldv.tp-v-fst{margin-top:calc(-1 * var(--cnt-v-p))}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-fldv.tp-v-fst>.tp-fldv_b{border-top-left-radius:var(--bs-br);border-top-right-radius:var(--bs-br)}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-tabv.tp-v-fst{margin-top:calc(-1 * var(--cnt-v-p))}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-tabv.tp-v-fst>.tp-tabv_i{border-top-left-radius:var(--bs-br);border-top-right-radius:var(--bs-br)}.tp-rotv.tp-v-disabled,.tp-rotv .tp-v-disabled{pointer-events:none}.tp-rotv.tp-v-hidden,.tp-rotv .tp-v-hidden{display:none}"),this.pool_.getAll().forEach((t=>{this.embedPluginStyle_(t)})),this.registerPlugin({plugins:[Ss,Es,Ft,Ms]})}},t.SeparatorApi=xt,t.SliderApi=Cs,t.TabApi=Dt,t.TabPageApi=Tt,t.TextApi=Ps,t.TpChangeEvent=i,t.VERSION=As,Object.defineProperty(t,"__esModule",{value:!0})}(e)},excalibur:e=>{"use strict";e.exports=t}},n={};function i(t){var s=n[t];if(void 0!==s)return s.exports;var o=n[t]={exports:{}};return e[t].call(o.exports,o,o.exports,i),o.exports}i.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e},i.d=(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var s={};return(()=>{"use strict";i.r(s),i.d(s,{DevTool:()=>o});var t=i("excalibur"),e=i("./node_modules/tweakpane/dist/tweakpane.js"),n=i("./picker-system.ts");class o{constructor(t){this.engine=t,this.pointerPos={x:0,y:0},this.highlightedEntities=[-1],this.selectedEntity=null,this.selectedEntityId=-1,this.pane=new e.Pane({title:"Excalibur Dev Tools",expanded:!0});const n=document.createElement("style");n.innerText=".excalibur-tweakpane-custom { width: 405px; }",document.head.appendChild(n),this.pane.element.parentElement.classList.add("excalibur-tweakpane-custom"),this._buildMain(),this.tabs=this.pane.addTab({pages:[{title:"Entity"},{title:"Screen"},{title:"Camera"},{title:"Clock"},{title:"Timers"},{title:"Physics"},{title:"Settings"}]}),this.selectedEntityTab=this.tabs.pages[0],this.screenTab=this.tabs.pages[1],this.cameraTab=this.tabs.pages[2],this.clockTab=this.tabs.pages[3],this.timerTab=this.tabs.pages[4],this.physicsTab=this.tabs.pages[5],this.debugTab=this.tabs.pages[6],this._installPickerSystemIfNeeded(t.currentScene),t.debug.transform.showPosition=!0,t.debug.entity.showName=!0,this.selectedEntityFolder=this.selectedEntityTab.addFolder({title:"Selected"}),this._buildScreenTab(),this._buildCameraTab(),this._buildClockTab(),this._buildTimersTab(),this._buildPhysicsTab(),this._buildDebugSettingsTab(),setInterval((()=>{this.update(this)}),30),this.addListeners()}addListeners(){this.engine.canvas.addEventListener("click",(()=>{-1!==this.highlightedEntities[0]&&this.selectEntityById(this.highlightedEntities[0])}))}selectEntityById(e){const n=this.engine;this.selectedEntityId=e,this.selectedEntity=n.currentScene.world.entityManager.getById(e),this._buildEntityUI(this.selectedEntity);const i=this.selectedEntity.get(t.TransformComponent);this._buildTransformUI(i);const s=this.selectedEntity.get(t.MotionComponent);if(this._buildMotionUI(s),this.selectedEntity instanceof t.ParticleEmitter)this._buildParticleEmitterUI(this.selectedEntity);else{const e=this.selectedEntity.get(t.GraphicsComponent);this._buildGraphicsUI(e);const n=this.selectedEntity.get(t.ColliderComponent),i=this.selectedEntity.get(t.BodyComponent);this._buildColliderUI(n,i)}}update(t){const e=t.engine,n=e.input.pointers.primary.lastWorldPos;this.pointerPos.x=n.x,this.pointerPos.y=n.y,this.pointerPosInput.refresh();const i=[...this.pickerSystem.lastFrameEntityToPointers.keys(),...this.pickerSystem.currentFrameEntityToPointers.keys()];0===i.length&&(i.push(-1),i.push(this.selectedEntityId)),this.highlightedEntities=i,e.debug.filter.useFilter=!0,e.debug.filter.ids=i,this.currentResolution.width===e.screen.resolution.width&&this.currentResolution.height===e.screen.resolution.height&&this.currentViewport.width===e.screen.viewport.width&&this.currentViewport.height===e.screen.viewport.height||(this.resolutionText.dispose(),this.viewportText.dispose(),this.resolutionText=this.screenFolder.addBlade({view:"text",label:"resolution",value:`(${e.screen.resolution.width}x${e.screen.resolution.height})`,parse:t=>String(t),index:0}),this.viewportText=this.screenFolder.addBlade({view:"text",label:"viewport",value:`(${e.screen.viewport.width.toFixed(0)}x${e.screen.viewport.height.toFixed(0)})`,parse:t=>String(t),index:1})),this._buildTimersTab()}_installPickerSystemIfNeeded(t){this.pickerSystem=t.world.systemManager.get(n.PickerSystem),this.pickerSystem||(this.pickerSystem=new n.PickerSystem,t.world.systemManager.addSystem(this.pickerSystem))}_buildMain(){this.pane.addInput({debug:!1},"debug").on("change",(()=>{this.engine.toggleDebug()})),this.pane.addMonitor(this.engine.clock.fpsSampler,"fps",{view:"graph",label:"fps (0 - 120)",min:0,max:120});let t,e="",n=[];for(let t in this.engine.scenes)this.engine.currentScene===this.engine.scenes[t]&&(e=t),n.push({text:t,value:t});this.pane.addBlade({view:"list",label:"current scene",options:n,value:e}).on("change",(e=>{this.engine.goToScene(e.value),this._installPickerSystemIfNeeded(this.engine.currentScene),t.dispose(),t=this.pane.addBlade({view:"text",label:"number of entities",value:this.engine.currentScene.world.entityManager.entities.length,parse:t=>String(t),index:3})})),t=this.pane.addBlade({view:"text",label:"number of entities",value:this.engine.currentScene.world.entityManager.entities.length,parse:t=>String(t),index:3}),this.pointerPos={x:10,y:10},this.pointerPosInput=this.pane.addInput(this,"pointerPos",{label:"pointer pos (world)"}),this.pane.addInput(this,"selectedEntityId",{label:"Select By Id"}).on("change",(t=>this.selectEntityById(t.value)))}_buildEntityUI(e){var n,i;this.selectedEntityFolder&&(this.selectedEntityFolder.dispose(),this.selectedEntityFolder=this.selectedEntityTab.addFolder({title:"Selected"})),this.selectedEntityFolder.addBlade({view:"text",label:"id",value:e.id.toString(),parse:t=>String(t)}),this.selectedEntityFolder.addInput(this.selectedEntity,"name"),this.selectedEntityFolder.addBlade({view:"text",label:"tags",value:e.tags.join(",")||"none",parse:t=>String(t)}),e instanceof t.Actor&&e.color&&this.selectedEntityFolder.addInput(this.selectedEntity,"color").on("change",(n=>{e.color=new t.Color(n.value.r,n.value.g,n.value.b,n.value.a)})),this.selectedEntityFolder.addBlade({view:"text",label:"parent",value:e.parent?`(${null===(n=e.parent)||void 0===n?void 0:n.id}) ${null===(i=e.parent)||void 0===i?void 0:i.name}`:"none",parse:t=>String(t)}),this.selectedEntityFolder.addBlade({view:"list",label:"children",options:e.children.map((t=>({text:`(${t.id}) ${t.name}`,value:t.id}))),value:e.children.length?e.children[0].id:"none"})}_buildColliderUI(e,n){var i,s;if(e){const o=this.selectedEntityFolder.addFolder({title:"Collider & Body"});o.addBlade({view:"text",label:"type",value:null!==(s=null===(i=e.get())||void 0===i?void 0:i.constructor.name)&&void 0!==s?s:"none",parse:t=>String(t)}),n&&(o.addBlade({view:"list",label:"collisionType",options:[t.CollisionType.Active,t.CollisionType.Fixed,t.CollisionType.Passive,t.CollisionType.PreventCollision].map((t=>({text:t,value:t}))),value:n.collisionType}).on("change",(t=>{n.collisionType=t.value})),o.addBlade({view:"list",label:"collisionGroup",options:[t.CollisionGroup.All,...t.CollisionGroupManager.groups].map((t=>({text:t.name,value:t}))),value:n.group}).on("change",(t=>{n.group=t.value})))}}_buildParticleEmitterUI(t){const e=this.selectedEntityFolder.addFolder({title:"Particles"});e.addInput(t,"isEmitting"),e.addInput(t,"emitRate"),e.addInput(t,"fadeFlag"),e.addInput(t,"particleLife",{min:100,max:1e4,step:100}),e.addInput(t,"width"),e.addInput(t,"height"),e.addInput(t,"minVel"),e.addInput(t,"maxVel"),e.addInput(t,"minAngle",{min:0,max:2*Math.PI,step:.1}),e.addInput(t,"maxAngle",{min:0,max:2*Math.PI,step:.1}),e.addInput(t,"minSize"),e.addInput(t,"maxSize"),e.addInput(t,"beginColor"),e.addInput(t,"endColor"),e.addInput(t,"opacity",{min:0,max:1,step:.01}),e.addInput(t,"randomRotation"),e.addInput(t,"particleRotationalVelocity")}_buildGraphicsUI(t){var e;if(t){const n=this.selectedEntityFolder.addFolder({title:"Graphics"});n.addInput(t,"anchor"),n.addInput(t,"opacity",{min:0,max:1,step:.05}),n.addInput(t,"visible");const i=[],s=[],o=t.current.map((t=>t.graphic)),r=[];let a=0;for(let e in t.graphics)i.push({text:e,value:a++}),s.push(t.graphics[e]),r.push(t.graphics[e]);let l=0;for(let t of o)-1===r.indexOf(t)&&(i.push({text:"anonymous"+l++,value:a}),s.push(t));n.addBlade({view:"list",label:"graphics",options:i,value:s.indexOf(null===(e=t.current[0])||void 0===e?void 0:e.graphic)}).on("change",(e=>{t.use(s[e.value])}))}}_buildMotionUI(t){if(t){const e=this.selectedEntityFolder.addFolder({title:"Motion"});e.addInput(t,"vel"),e.addInput(t,"acc"),e.addInput(t,"angularVelocity",{step:.1}),e.addInput(t,"scaleFactor"),e.addInput(t,"inertia")}}_buildTransformUI(e){if(e){const n=this.selectedEntityFolder.addFolder({title:"Transform"});n.addBlade({view:"list",label:"coord plane",options:[t.CoordPlane.World,t.CoordPlane.Screen].map((t=>({text:t,value:t}))),value:e.coordPlane}).on("change",(t=>e.coordPlane=t.value));const i=n.addInput(e,"pos"),s=n.addInput(e,"rotation",{min:0,max:2*Math.PI}),o=n.addInput(e,"scale");n.addSeparator();const r=n.addInput(e,"globalPos",{label:"global pos"}),a=n.addInput(e,"globalRotation",{label:"global rot",min:0,max:2*Math.PI}),l=n.addInput(e,"globalScale",{label:"global pos"});r.on("change",(()=>i.refresh())),i.on("change",(()=>r.refresh())),a.on("change",(()=>s.refresh())),s.on("change",(()=>a.refresh())),l.on("change",(()=>o.refresh())),o.on("change",(()=>l.refresh())),n.addInput(e,"z",{label:"z-index"})}}_buildScreenTab(){this.screenFolder=this.screenTab.addFolder({title:"Screen"}),this.currentResolution=this.engine.screen.resolution,this.currentViewport=this.engine.screen.viewport,this.resolutionText=this.screenFolder.addBlade({view:"text",label:"resolution",value:`(${this.engine.screen.resolution.width}x${this.engine.screen.resolution.height})`,parse:t=>String(t),index:0}),this.viewportText=this.screenFolder.addBlade({view:"text",label:"viewport",value:`(${this.engine.screen.viewport.width.toFixed(0)}x${this.engine.screen.viewport.height.toFixed(0)})`,parse:t=>String(t),index:1}),this.screenFolder.addButton({title:"Fullscreen"}).on("click",(()=>{this.engine.screen.goFullScreen()}))}_buildCameraTab(){const t=this.cameraTab.addFolder({title:"Camera"});t.addInput(this.engine.currentScene.camera,"zoom",{min:.01,max:10,step:.5}),t.addInput(this.engine.currentScene.camera,"pos")}_buildClockTab(){const e=this.clockTab.addFolder({title:"Clock"});let n=this.engine.clock instanceof t.TestClock,i=16;const s=e.addButton({title:"step",disabled:!n,index:2}).on("click",(()=>this.engine.clock.step(i)));e.addBlade({view:"slider",label:"step (ms)",min:1,max:100,step:16,value:i}).on("change",(t=>i=t.value)),e.addButton({title:"Use Test Clock",index:0}).on("click",(()=>{this.engine.debug.useTestClock(),n=!0,s.disabled=!1})),e.addButton({title:"Use Standard Clock",index:1}).on("click",(()=>{this.engine.debug.useStandardClock(),n=!1,s.disabled=!0})),this.pane.addSeparator();const o=e.addButton({title:"Stop",disabled:!1}),r=e.addButton({title:"Start",disabled:!0});o.on("click",(()=>{this.engine.clock.stop(),r.disabled=!1,o.disabled=!0})),r.on("click",(()=>{this.engine.clock.start(),o.disabled=!1,r.disabled=!0}))}_buildTimersTab(){this.timerTab,this._timersFolder&&this._timersFolder.dispose(),this._timersFolder=this.timerTab.addFolder({title:"Timers"});for(let t of this.engine.currentScene.timers){let e=t.repeats&&-1===t.maxNumberOfRepeats?"repeats":t._numberOfTicks+1+" of "+(-1===t.maxNumberOfRepeats?1:t.maxNumberOfRepeats);t.isRunning||(e="stopped"),t.complete&&(e="complete"),this._timersFolder.addBlade({view:"text",label:`timer(${t.id})`,value:`${e} next(${t.timeToNextAction.toFixed(0)}ms)`,parse:t=>String(t)})}}_buildPhysicsTab(){const e=this.physicsTab,n={};for(let e in t.Physics)n[e]=t.Physics[e];e.addInput(n,"enabled").on("change",(e=>t.Physics.enabled=e.value)),e.addInput(n,"acc");const i=e.addInput(n,"collisionResolutionStrategy");e.addButton({title:"Use Arcade"}).on("click",(()=>{t.Physics.useArcadePhysics(),n.collisionResolutionStrategy=t.Physics.collisionResolutionStrategy,i.refresh()})),e.addButton({title:"Use Realistic"}).on("click",(()=>{t.Physics.useRealisticPhysics(),n.collisionResolutionStrategy=t.Physics.collisionResolutionStrategy,i.refresh()})),e.addInput(n,"positionIterations",{min:1,max:30,step:1}).on("change",(e=>t.Physics.positionIterations=e.value)),e.addInput(n,"velocityIterations",{min:1,max:30,step:1}).on("change",(e=>t.Physics.velocityIterations=e.value)),e.addInput(n,"checkForFastBodies").on("change",(e=>t.Physics.checkForFastBodies=e.value))}_buildDebugSettingsTab(){const t=this.debugTab;for(let e of["entity","transform","motion","body","collider","physics","graphics","camera"]){let n=t.addFolder({title:e});if(this.engine.debug[e])for(let t in this.engine.debug[e])if(t)if(t.toLocaleLowerCase().includes("color"))n.addInput(this.engine.debug[e],t);else{if(Array.isArray(this.engine.debug[e][t]))continue;n.addInput(this.engine.debug[e],t)}}}}})(),s})()})); -//# sourceMappingURL=dev-tools.js.map \ No newline at end of file +!(function (t, e) { + 'object' == typeof exports && 'object' == typeof module + ? (module.exports = e(require('excalibur'))) + : 'function' == typeof define && define.amd + ? define(['excalibur'], e) + : 'object' == typeof exports + ? (exports.ex = e(require('excalibur'))) + : ((t.ex = t.ex || {}), (t.ex.DevTools = e(t.ex))); +})(self, function (t) { + return (() => { + var e = { + './picker-system.ts': (t, e, n) => { + 'use strict'; + n.r(e), n.d(e, { PickerSystem: () => s }); + var i = n('excalibur'); + class s extends i.System { + constructor() { + super(...arguments), + (this.types = ['ex.transform']), + (this.systemType = i.SystemType.Update), + (this.priority = 99), + (this.lastFrameEntityToPointers = new Map()), + (this.currentFrameEntityToPointers = new Map()); + } + initialize(t) { + (this._engine = t.engine), (this._receiver = this._engine.input.pointers); + } + addPointerToEntity(t, e) { + if (!this.currentFrameEntityToPointers.has(t.id)) return void this.currentFrameEntityToPointers.set(t.id, [e]); + const n = this.currentFrameEntityToPointers.get(t.id); + this.currentFrameEntityToPointers.set(t.id, n.concat(e)); + } + _processPointerToEntity(t) { + var e; + let n, s, o; + for (const r of t) + if (!(r instanceof i.Particle)) { + if (((n = r.get(i.TransformComponent)), (s = r.get(i.ColliderComponent)), s)) { + const t = s.get(); + if (t) + for (const [e, s] of this._receiver.currentFramePointerCoords.entries()) + t.contains(n.coordPlane === i.CoordPlane.World ? s.worldPos : s.screenPos) && this.addPointerToEntity(r, e); + } + if (((o = r.get(i.GraphicsComponent)), o)) { + const t = o.localBounds.transform(n.getGlobalMatrix()); + for (const [e, s] of this._receiver.currentFramePointerCoords.entries()) + t.contains(n.coordPlane === i.CoordPlane.World ? s.worldPos : s.screenPos) && this.addPointerToEntity(r, e); + } + if ( + (!(null === (e = null == o ? void 0 : o.current) || void 0 === e ? void 0 : e.length) && + !(null == s ? void 0 : s.get())) || + r instanceof i.ParticleEmitter + ) { + const t = i.BoundingBox.fromDimension(100, 100).transform(n.getGlobalMatrix()); + for (const [e, s] of this._receiver.currentFramePointerCoords.entries()) + t.contains(n.coordPlane === i.CoordPlane.World ? s.worldPos : s.screenPos) && this.addPointerToEntity(r, e); + } + } + } + update(t, e) { + this._processPointerToEntity(t), + this.lastFrameEntityToPointers.clear(), + (this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers)), + this.currentFrameEntityToPointers.clear(); + } + } + }, + './node_modules/tweakpane/dist/tweakpane.js': function (t, e) { + !(function (t) { + 'use strict'; + class e { + constructor(t) { + this.controller_ = t; + } + get disabled() { + return this.controller_.viewProps.get('disabled'); + } + set disabled(t) { + this.controller_.viewProps.set('disabled', t); + } + get hidden() { + return this.controller_.viewProps.get('hidden'); + } + set hidden(t) { + this.controller_.viewProps.set('hidden', t); + } + dispose() { + this.controller_.viewProps.set('disposed', !0); + } + } + class n { + constructor(t) { + this.target = t; + } + } + class i extends n { + constructor(t, e, n, i) { + super(t), (this.value = e), (this.presetKey = n), (this.last = null == i || i); + } + } + class s extends n { + constructor(t, e, n) { + super(t), (this.value = e), (this.presetKey = n); + } + } + class o extends n { + constructor(t, e) { + super(t), (this.expanded = e); + } + } + function r(t) { + return null == t; + } + function a(t, e) { + if (t.length !== e.length) return !1; + for (let n = 0; n < t.length; n++) if (t[n] !== e[n]) return !1; + return !0; + } + const l = { + alreadydisposed: () => 'View has been already disposed', + invalidparams: (t) => `Invalid parameters for '${t.name}'`, + nomatchingcontroller: (t) => `No matching controller for '${t.key}'`, + nomatchingview: (t) => `No matching view for '${JSON.stringify(t.params)}'`, + notbindable: () => 'Value is not bindable', + propertynotfound: (t) => `Property '${t.name}' not found`, + shouldneverhappen: () => 'This error should never happen' + }; + class p { + constructor(t) { + var e; + (this.message = null !== (e = l[t.type](t.context)) && void 0 !== e ? e : 'Unexpected error'), + (this.name = this.constructor.name), + (this.stack = new Error(this.message).stack), + (this.type = t.type); + } + static alreadyDisposed() { + return new p({ type: 'alreadydisposed' }); + } + static notBindable() { + return new p({ type: 'notbindable' }); + } + static propertyNotFound(t) { + return new p({ type: 'propertynotfound', context: { name: t } }); + } + static shouldNeverHappen() { + return new p({ type: 'shouldneverhappen' }); + } + } + class d { + constructor(t, e, n) { + (this.obj_ = t), (this.key_ = e), (this.presetKey_ = null != n ? n : e); + } + static isBindable(t) { + return null !== t && 'object' == typeof t; + } + get key() { + return this.key_; + } + get presetKey() { + return this.presetKey_; + } + read() { + return this.obj_[this.key_]; + } + write(t) { + this.obj_[this.key_] = t; + } + writeProperty(t, e) { + const n = this.read(); + if (!d.isBindable(n)) throw p.notBindable(); + if (!(t in n)) throw p.propertyNotFound(t); + n[t] = e; + } + } + class c extends e { + get label() { + return this.controller_.props.get('label'); + } + set label(t) { + this.controller_.props.set('label', t); + } + get title() { + var t; + return null !== (t = this.controller_.valueController.props.get('title')) && void 0 !== t ? t : ''; + } + set title(t) { + this.controller_.valueController.props.set('title', t); + } + on(t, e) { + const i = e.bind(this); + return ( + this.controller_.valueController.emitter.on(t, () => { + i(new n(this)); + }), + this + ); + } + } + class h { + constructor() { + this.observers_ = {}; + } + on(t, e) { + let n = this.observers_[t]; + return n || (n = this.observers_[t] = []), n.push({ handler: e }), this; + } + off(t, e) { + const n = this.observers_[t]; + return n && (this.observers_[t] = n.filter((t) => t.handler !== e)), this; + } + emit(t, e) { + const n = this.observers_[t]; + n && + n.forEach((t) => { + t.handler(e); + }); + } + } + const u = 'tp'; + function v(t) { + return (e, n) => [u, '-', t, 'v', e ? `_${e}` : '', n ? `-${n}` : ''].join(''); + } + function m(t) { + return t.rawValue; + } + function b(t, e) { + var n, i; + t.emitter.on('change', ((n = m), (i = e), (t) => i(n(t)))), e(t.rawValue); + } + function g(t, e, n) { + b(t.value(e), n); + } + function _(t, e) { + return (n) => { + !(function (t, e, n) { + n ? t.classList.add(e) : t.classList.remove(e); + })(t, e, n); + }; + } + function f(t, e) { + b(t, (t) => { + e.textContent = null != t ? t : ''; + }); + } + const w = v('btn'); + class x { + constructor(t, e) { + (this.element = t.createElement('div')), this.element.classList.add(w()), e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('button'); + n.classList.add(w('b')), e.viewProps.bindDisabled(n), this.element.appendChild(n), (this.buttonElement = n); + const i = t.createElement('div'); + i.classList.add(w('t')), f(e.props.value('title'), i), this.buttonElement.appendChild(i); + } + } + class y { + constructor(t, e) { + (this.emitter = new h()), + (this.onClick_ = this.onClick_.bind(this)), + (this.props = e.props), + (this.viewProps = e.viewProps), + (this.view = new x(t, { props: this.props, viewProps: this.viewProps })), + this.view.buttonElement.addEventListener('click', this.onClick_); + } + onClick_() { + this.emitter.emit('click', { sender: this }); + } + } + class C { + constructor(t, e) { + var n; + (this.constraint_ = null == e ? void 0 : e.constraint), + (this.equals_ = null !== (n = null == e ? void 0 : e.equals) && void 0 !== n ? n : (t, e) => t === e), + (this.emitter = new h()), + (this.rawValue_ = t); + } + get constraint() { + return this.constraint_; + } + get rawValue() { + return this.rawValue_; + } + set rawValue(t) { + this.setRawValue(t, { forceEmit: !1, last: !0 }); + } + setRawValue(t, e) { + const n = null != e ? e : { forceEmit: !1, last: !0 }, + i = this.constraint_ ? this.constraint_.constrain(t) : t; + (!this.equals_(this.rawValue_, i) || n.forceEmit) && + (this.emitter.emit('beforechange', { sender: this }), + (this.rawValue_ = i), + this.emitter.emit('change', { options: n, rawValue: i, sender: this })); + } + } + class P { + constructor(t) { + (this.emitter = new h()), (this.value_ = t); + } + get rawValue() { + return this.value_; + } + set rawValue(t) { + this.setRawValue(t, { forceEmit: !1, last: !0 }); + } + setRawValue(t, e) { + const n = null != e ? e : { forceEmit: !1, last: !0 }; + (this.value_ !== t || n.forceEmit) && + (this.emitter.emit('beforechange', { sender: this }), + (this.value_ = t), + this.emitter.emit('change', { options: n, rawValue: this.value_, sender: this })); + } + } + function E(t, e) { + const n = null == e ? void 0 : e.constraint, + i = null == e ? void 0 : e.equals; + return n || i ? new C(t, e) : new P(t); + } + class k { + constructor(t) { + (this.emitter = new h()), (this.valMap_ = t); + for (const t in this.valMap_) + this.valMap_[t].emitter.on('change', () => { + this.emitter.emit('change', { key: t, sender: this }); + }); + } + static createCore(t) { + return Object.keys(t).reduce((e, n) => Object.assign(e, { [n]: E(t[n]) }), {}); + } + static fromObject(t) { + const e = this.createCore(t); + return new k(e); + } + get(t) { + return this.valMap_[t].rawValue; + } + set(t, e) { + this.valMap_[t].rawValue = e; + } + value(t) { + return this.valMap_[t]; + } + } + function V(t) { + return (e) => (n) => { + if (!e && void 0 === n) return { succeeded: !1, value: void 0 }; + if (e && void 0 === n) return { succeeded: !0, value: void 0 }; + const i = t(n); + return void 0 !== i ? { succeeded: !0, value: i } : { succeeded: !1, value: void 0 }; + }; + } + function S(t) { + return { + custom: (e) => V(e)(t), + boolean: V((t) => ('boolean' == typeof t ? t : void 0))(t), + number: V((t) => ('number' == typeof t ? t : void 0))(t), + string: V((t) => ('string' == typeof t ? t : void 0))(t), + function: V((t) => ('function' == typeof t ? t : void 0))(t), + constant: (e) => V((t) => (t === e ? e : void 0))(t), + raw: V((t) => t)(t), + object: (e) => + V((t) => { + if (null !== (n = t) && 'object' == typeof n) + return (function (t, e) { + return Object.keys(e).reduce((n, i) => { + if (void 0 === n) return; + const s = (0, e[i])(t[i]); + return s.succeeded ? Object.assign(Object.assign({}, n), { [i]: s.value }) : void 0; + }, {}); + })(t, e); + var n; + })(t), + array: (e) => + V((t) => { + if (Array.isArray(t)) + return ( + (n = e), + t.reduce((t, e) => { + if (void 0 === t) return; + const i = n(e); + return i.succeeded && void 0 !== i.value ? [...t, i.value] : void 0; + }, []) + ); + var n; + })(t) + }; + } + const M = { optional: S(!0), required: S(!1) }; + function L(t, e) { + const n = M.required.object(e)(t); + return n.succeeded ? n.value : void 0; + } + const A = v(''), + I = { veryfirst: 'vfst', first: 'fst', last: 'lst', verylast: 'vlst' }; + class T { + constructor(t) { + (this.parent_ = null), (this.blade = t.blade), (this.view = t.view), (this.viewProps = t.viewProps); + const e = this.view.element; + this.blade.value('positions').emitter.on('change', () => { + ['veryfirst', 'first', 'last', 'verylast'].forEach((t) => { + e.classList.remove(A(void 0, I[t])); + }), + this.blade.get('positions').forEach((t) => { + e.classList.add(A(void 0, I[t])); + }); + }), + this.viewProps.handleDispose(() => { + !(function (t) { + t && t.parentElement && t.parentElement.removeChild(t); + })(e); + }); + } + get parent() { + return this.parent_; + } + } + const D = 'http://www.w3.org/2000/svg'; + function j(t) { + t.offsetHeight; + } + function B(t) { + return void 0 !== t.ontouchstart; + } + function R() { + return new Function('return this')().document; + } + const F = { + check: '', + dropdown: '', + p2dpad: '' + }; + function U(t, e) { + const n = t.createElementNS(D, 'svg'); + return (n.innerHTML = F[e]), n; + } + function O(t, e, n) { + t.insertBefore(e, t.children[n]); + } + function K(t) { + t.parentElement && t.parentElement.removeChild(t); + } + function N(t) { + for (; t.children.length > 0; ) t.removeChild(t.children[0]); + } + function $(t) { + return t.relatedTarget ? t.relatedTarget : 'explicitOriginalTarget' in t ? t.explicitOriginalTarget : null; + } + const z = v('lbl'); + class H { + constructor(t, e) { + (this.element = t.createElement('div')), this.element.classList.add(z()), e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('div'); + n.classList.add(z('l')), + g(e.props, 'label', (e) => { + r(e) + ? this.element.classList.add(z(void 0, 'nol')) + : (this.element.classList.remove(z(void 0, 'nol')), + (function (t) { + for (; t.childNodes.length > 0; ) t.removeChild(t.childNodes[0]); + })(n), + n.appendChild( + (function (t, e) { + const n = t.createDocumentFragment(); + return ( + e + .split('\n') + .map((e) => t.createTextNode(e)) + .forEach((e, i) => { + i > 0 && n.appendChild(t.createElement('br')), n.appendChild(e); + }), + n + ); + })(t, e) + )); + }), + this.element.appendChild(n), + (this.labelElement = n); + const i = t.createElement('div'); + i.classList.add(z('v')), this.element.appendChild(i), (this.valueElement = i); + } + } + class q extends T { + constructor(t, e) { + const n = e.valueController.viewProps; + super(Object.assign(Object.assign({}, e), { view: new H(t, { props: e.props, viewProps: n }), viewProps: n })), + (this.props = e.props), + (this.valueController = e.valueController), + this.view.valueElement.appendChild(this.valueController.view.element); + } + } + const G = { + id: 'button', + type: 'blade', + accept(t) { + const e = M, + n = L(t, { title: e.required.string, view: e.required.constant('button'), label: e.optional.string }); + return n ? { params: n } : null; + }, + controller: (t) => + new q(t.document, { + blade: t.blade, + props: k.fromObject({ label: t.params.label }), + valueController: new y(t.document, { props: k.fromObject({ title: t.params.title }), viewProps: t.viewProps }) + }), + api: (t) => (t.controller instanceof q && t.controller.valueController instanceof y ? new c(t.controller) : null) + }; + class Y extends T { + constructor(t) { + super(t), (this.value = t.value); + } + } + function W() { + return new k({ positions: E([], { equals: a }) }); + } + class X extends k { + constructor(t) { + super(t); + } + static create(t) { + const e = { completed: !0, expanded: t, expandedHeight: null, shouldFixHeight: !1, temporaryExpanded: null }, + n = k.createCore(e); + return new X(n); + } + get styleExpanded() { + var t; + return null !== (t = this.get('temporaryExpanded')) && void 0 !== t ? t : this.get('expanded'); + } + get styleHeight() { + if (!this.styleExpanded) return '0'; + const t = this.get('expandedHeight'); + return this.get('shouldFixHeight') && !r(t) ? `${t}px` : 'auto'; + } + bindExpandedClass(t, e) { + g(this, 'expanded', () => { + this.styleExpanded ? t.classList.add(e) : t.classList.remove(e); + }); + } + } + function Q(t, e) { + e.style.height = t.styleHeight; + } + function J(t, e) { + t.value('expanded').emitter.on('beforechange', () => { + t.set('completed', !1), + r(t.get('expandedHeight')) && + t.set( + 'expandedHeight', + (function (t, e) { + let n = 0; + return ( + (function (t, e) { + const n = t.style.transition; + (t.style.transition = 'none'), e(), (t.style.transition = n); + })(e, () => { + t.set('expandedHeight', null), + t.set('temporaryExpanded', !0), + j(e), + (n = e.clientHeight), + t.set('temporaryExpanded', null), + j(e); + }), + n + ); + })(t, e) + ), + t.set('shouldFixHeight', !0), + j(e); + }), + t.emitter.on('change', () => { + Q(t, e); + }), + Q(t, e), + e.addEventListener('transitionend', (e) => { + 'height' === e.propertyName && (t.set('shouldFixHeight', !1), t.set('expandedHeight', null), t.set('completed', !0)); + }); + } + class Z extends e { + constructor(t, e) { + super(t), (this.rackApi_ = e); + } + } + class tt { + constructor(t) { + (this.emitter = new h()), + (this.items_ = []), + (this.cache_ = new Set()), + (this.onSubListAdd_ = this.onSubListAdd_.bind(this)), + (this.onSubListRemove_ = this.onSubListRemove_.bind(this)), + (this.extract_ = t); + } + get items() { + return this.items_; + } + allItems() { + return Array.from(this.cache_); + } + find(t) { + for (const e of this.allItems()) if (t(e)) return e; + return null; + } + includes(t) { + return this.cache_.has(t); + } + add(t, e) { + if (this.includes(t)) throw p.shouldNeverHappen(); + const n = void 0 !== e ? e : this.items_.length; + this.items_.splice(n, 0, t), this.cache_.add(t); + const i = this.extract_(t); + i && + (i.emitter.on('add', this.onSubListAdd_), + i.emitter.on('remove', this.onSubListRemove_), + i.allItems().forEach((t) => { + this.cache_.add(t); + })), + this.emitter.emit('add', { index: n, item: t, root: this, target: this }); + } + remove(t) { + const e = this.items_.indexOf(t); + if (e < 0) return; + this.items_.splice(e, 1), this.cache_.delete(t); + const n = this.extract_(t); + n && (n.emitter.off('add', this.onSubListAdd_), n.emitter.off('remove', this.onSubListRemove_)), + this.emitter.emit('remove', { index: e, item: t, root: this, target: this }); + } + onSubListAdd_(t) { + this.cache_.add(t.item), this.emitter.emit('add', { index: t.index, item: t.item, root: this, target: t.target }); + } + onSubListRemove_(t) { + this.cache_.delete(t.item), this.emitter.emit('remove', { index: t.index, item: t.item, root: this, target: t.target }); + } + } + class et extends e { + constructor(t) { + super(t), + (this.onBindingChange_ = this.onBindingChange_.bind(this)), + (this.emitter_ = new h()), + this.controller_.binding.emitter.on('change', this.onBindingChange_); + } + get label() { + return this.controller_.props.get('label'); + } + set label(t) { + this.controller_.props.set('label', t); + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + refresh() { + this.controller_.binding.read(); + } + onBindingChange_(t) { + const e = t.sender.target.read(); + this.emitter_.emit('change', { event: new i(this, e, this.controller_.binding.target.presetKey, t.options.last) }); + } + } + class nt extends q { + constructor(t, e) { + super(t, e), (this.binding = e.binding); + } + } + class it extends e { + constructor(t) { + super(t), + (this.onBindingUpdate_ = this.onBindingUpdate_.bind(this)), + (this.emitter_ = new h()), + this.controller_.binding.emitter.on('update', this.onBindingUpdate_); + } + get label() { + return this.controller_.props.get('label'); + } + set label(t) { + this.controller_.props.set('label', t); + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + refresh() { + this.controller_.binding.read(); + } + onBindingUpdate_(t) { + const e = t.sender.target.read(); + this.emitter_.emit('update', { event: new s(this, e, this.controller_.binding.target.presetKey) }); + } + } + class st extends q { + constructor(t, e) { + super(t, e), + (this.binding = e.binding), + this.viewProps.bindDisabled(this.binding.ticker), + this.viewProps.handleDispose(() => { + this.binding.dispose(); + }); + } + } + function ot(t) { + return t instanceof lt ? t.apiSet_ : t instanceof Z ? t.rackApi_.apiSet_ : null; + } + function rt(t, e) { + const n = t.find((t) => t.controller_ === e); + if (!n) throw p.shouldNeverHappen(); + return n; + } + function at(t, e, n) { + if (!d.isBindable(t)) throw p.notBindable(); + return new d(t, e, n); + } + class lt extends e { + constructor(t, e) { + super(t), + (this.onRackAdd_ = this.onRackAdd_.bind(this)), + (this.onRackRemove_ = this.onRackRemove_.bind(this)), + (this.onRackInputChange_ = this.onRackInputChange_.bind(this)), + (this.onRackMonitorUpdate_ = this.onRackMonitorUpdate_.bind(this)), + (this.emitter_ = new h()), + (this.apiSet_ = new tt(ot)), + (this.pool_ = e); + const n = this.controller_.rack; + n.emitter.on('add', this.onRackAdd_), + n.emitter.on('remove', this.onRackRemove_), + n.emitter.on('inputchange', this.onRackInputChange_), + n.emitter.on('monitorupdate', this.onRackMonitorUpdate_), + n.children.forEach((t) => { + this.setUpApi_(t); + }); + } + get children() { + return this.controller_.rack.children.map((t) => rt(this.apiSet_, t)); + } + addInput(t, e, n) { + const i = n || {}, + s = this.controller_.view.element.ownerDocument, + o = this.pool_.createInput(s, at(t, e, i.presetKey), i), + r = new et(o); + return this.add(r, i.index); + } + addMonitor(t, e, n) { + const i = n || {}, + s = this.controller_.view.element.ownerDocument, + o = this.pool_.createMonitor(s, at(t, e), i), + r = new it(o); + return this.add(r, i.index); + } + addFolder(t) { + return (function (t, e) { + return t.addBlade(Object.assign(Object.assign({}, e), { view: 'folder' })); + })(this, t); + } + addButton(t) { + return (function (t, e) { + return t.addBlade(Object.assign(Object.assign({}, e), { view: 'button' })); + })(this, t); + } + addSeparator(t) { + return (function (t, e) { + const n = e || {}; + return t.addBlade(Object.assign(Object.assign({}, n), { view: 'separator' })); + })(this, t); + } + addTab(t) { + return (function (t, e) { + return t.addBlade(Object.assign(Object.assign({}, e), { view: 'tab' })); + })(this, t); + } + add(t, e) { + this.controller_.rack.add(t.controller_, e); + const n = this.apiSet_.find((e) => e.controller_ === t.controller_); + return n && this.apiSet_.remove(n), this.apiSet_.add(t), t; + } + remove(t) { + this.controller_.rack.remove(t.controller_); + } + addBlade(t) { + const e = this.controller_.view.element.ownerDocument, + n = this.pool_.createBlade(e, t), + i = this.pool_.createBladeApi(n); + return this.add(i, t.index); + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + setUpApi_(t) { + this.apiSet_.find((e) => e.controller_ === t) || this.apiSet_.add(this.pool_.createBladeApi(t)); + } + onRackAdd_(t) { + this.setUpApi_(t.bladeController); + } + onRackRemove_(t) { + if (t.isRoot) { + const e = rt(this.apiSet_, t.bladeController); + this.apiSet_.remove(e); + } + } + onRackInputChange_(t) { + const e = t.bladeController; + if (e instanceof nt) { + const n = rt(this.apiSet_, e), + s = e.binding; + this.emitter_.emit('change', { event: new i(n, s.target.read(), s.target.presetKey, t.options.last) }); + } else if (e instanceof Y) { + const n = rt(this.apiSet_, e); + this.emitter_.emit('change', { event: new i(n, e.value.rawValue, void 0, t.options.last) }); + } + } + onRackMonitorUpdate_(t) { + if (!(t.bladeController instanceof st)) throw p.shouldNeverHappen(); + const e = rt(this.apiSet_, t.bladeController), + n = t.bladeController.binding; + this.emitter_.emit('update', { event: new s(e, n.target.read(), n.target.presetKey) }); + } + } + class pt extends Z { + constructor(t, e) { + super(t, new lt(t.rackController, e)), + (this.emitter_ = new h()), + this.controller_.foldable.value('expanded').emitter.on('change', (t) => { + this.emitter_.emit('fold', { event: new o(this, t.sender.rawValue) }); + }), + this.rackApi_.on('change', (t) => { + this.emitter_.emit('change', { event: t }); + }), + this.rackApi_.on('update', (t) => { + this.emitter_.emit('update', { event: t }); + }); + } + get expanded() { + return this.controller_.foldable.get('expanded'); + } + set expanded(t) { + this.controller_.foldable.set('expanded', t); + } + get title() { + return this.controller_.props.get('title'); + } + set title(t) { + this.controller_.props.set('title', t); + } + get children() { + return this.rackApi_.children; + } + addInput(t, e, n) { + return this.rackApi_.addInput(t, e, n); + } + addMonitor(t, e, n) { + return this.rackApi_.addMonitor(t, e, n); + } + addFolder(t) { + return this.rackApi_.addFolder(t); + } + addButton(t) { + return this.rackApi_.addButton(t); + } + addSeparator(t) { + return this.rackApi_.addSeparator(t); + } + addTab(t) { + return this.rackApi_.addTab(t); + } + add(t, e) { + return this.rackApi_.add(t, e); + } + remove(t) { + this.rackApi_.remove(t); + } + addBlade(t) { + return this.rackApi_.addBlade(t); + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + } + class dt extends T { + constructor(t) { + super({ blade: t.blade, view: t.view, viewProps: t.rackController.viewProps }), (this.rackController = t.rackController); + } + } + class ct { + constructor(t, e) { + const n = v(e.viewName); + (this.element = t.createElement('div')), this.element.classList.add(n()), e.viewProps.bindClassModifiers(this.element); + } + } + function ht(t) { + return t instanceof mt ? t.rack : t instanceof dt ? t.rackController.rack : null; + } + function ut(t) { + const e = ht(t); + return e ? e.bcSet_ : null; + } + class vt { + constructor(t) { + var e; + (this.onBladePositionsChange_ = this.onBladePositionsChange_.bind(this)), + (this.onSetAdd_ = this.onSetAdd_.bind(this)), + (this.onSetRemove_ = this.onSetRemove_.bind(this)), + (this.onChildDispose_ = this.onChildDispose_.bind(this)), + (this.onChildPositionsChange_ = this.onChildPositionsChange_.bind(this)), + (this.onChildInputChange_ = this.onChildInputChange_.bind(this)), + (this.onChildMonitorUpdate_ = this.onChildMonitorUpdate_.bind(this)), + (this.onChildValueChange_ = this.onChildValueChange_.bind(this)), + (this.onChildViewPropsChange_ = this.onChildViewPropsChange_.bind(this)), + (this.onDescendantLayout_ = this.onDescendantLayout_.bind(this)), + (this.onDescendantInputChange_ = this.onDescendantInputChange_.bind(this)), + (this.onDescendantMonitorUpdate_ = this.onDescendantMonitorUpdate_.bind(this)), + (this.emitter = new h()), + (this.blade_ = null != t ? t : null), + null === (e = this.blade_) || void 0 === e || e.value('positions').emitter.on('change', this.onBladePositionsChange_), + (this.bcSet_ = new tt(ut)), + this.bcSet_.emitter.on('add', this.onSetAdd_), + this.bcSet_.emitter.on('remove', this.onSetRemove_); + } + get children() { + return this.bcSet_.items; + } + add(t, e) { + t.parent && t.parent.remove(t), (t.parent_ = this), this.bcSet_.add(t, e); + } + remove(t) { + (t.parent_ = null), this.bcSet_.remove(t); + } + find(t) { + return this.bcSet_.allItems().filter((e) => e instanceof t); + } + onSetAdd_(t) { + this.updatePositions_(); + const e = t.target === t.root; + if ((this.emitter.emit('add', { bladeController: t.item, index: t.index, isRoot: e, sender: this }), !e)) return; + const n = t.item; + if ( + (n.viewProps.emitter.on('change', this.onChildViewPropsChange_), + n.blade.value('positions').emitter.on('change', this.onChildPositionsChange_), + n.viewProps.handleDispose(this.onChildDispose_), + n instanceof nt) + ) + n.binding.emitter.on('change', this.onChildInputChange_); + else if (n instanceof st) n.binding.emitter.on('update', this.onChildMonitorUpdate_); + else if (n instanceof Y) n.value.emitter.on('change', this.onChildValueChange_); + else { + const t = ht(n); + if (t) { + const e = t.emitter; + e.on('layout', this.onDescendantLayout_), + e.on('inputchange', this.onDescendantInputChange_), + e.on('monitorupdate', this.onDescendantMonitorUpdate_); + } + } + } + onSetRemove_(t) { + this.updatePositions_(); + const e = t.target === t.root; + if ((this.emitter.emit('remove', { bladeController: t.item, isRoot: e, sender: this }), !e)) return; + const n = t.item; + if (n instanceof nt) n.binding.emitter.off('change', this.onChildInputChange_); + else if (n instanceof st) n.binding.emitter.off('update', this.onChildMonitorUpdate_); + else if (n instanceof Y) n.value.emitter.off('change', this.onChildValueChange_); + else { + const t = ht(n); + if (t) { + const e = t.emitter; + e.off('layout', this.onDescendantLayout_), + e.off('inputchange', this.onDescendantInputChange_), + e.off('monitorupdate', this.onDescendantMonitorUpdate_); + } + } + } + updatePositions_() { + const t = this.bcSet_.items.filter((t) => !t.viewProps.get('hidden')), + e = t[0], + n = t[t.length - 1]; + this.bcSet_.items.forEach((t) => { + const i = []; + t === e && (i.push('first'), (this.blade_ && !this.blade_.get('positions').includes('veryfirst')) || i.push('veryfirst')), + t === n && (i.push('last'), (this.blade_ && !this.blade_.get('positions').includes('verylast')) || i.push('verylast')), + t.blade.set('positions', i); + }); + } + onChildPositionsChange_() { + this.updatePositions_(), this.emitter.emit('layout', { sender: this }); + } + onChildViewPropsChange_(t) { + this.updatePositions_(), this.emitter.emit('layout', { sender: this }); + } + onChildDispose_() { + this.bcSet_.items + .filter((t) => t.viewProps.get('disposed')) + .forEach((t) => { + this.bcSet_.remove(t); + }); + } + onChildInputChange_(t) { + const e = (function (t, e) { + for (let n = 0; n < t.length; n++) { + const i = t[n]; + if (i instanceof nt && i.binding === e) return i; + } + return null; + })(this.find(nt), t.sender); + if (!e) throw p.shouldNeverHappen(); + this.emitter.emit('inputchange', { bladeController: e, options: t.options, sender: this }); + } + onChildMonitorUpdate_(t) { + const e = (function (t, e) { + for (let n = 0; n < t.length; n++) { + const i = t[n]; + if (i instanceof st && i.binding === e) return i; + } + return null; + })(this.find(st), t.sender); + if (!e) throw p.shouldNeverHappen(); + this.emitter.emit('monitorupdate', { bladeController: e, sender: this }); + } + onChildValueChange_(t) { + const e = (function (t, e) { + for (let n = 0; n < t.length; n++) { + const i = t[n]; + if (i instanceof Y && i.value === e) return i; + } + return null; + })(this.find(Y), t.sender); + if (!e) throw p.shouldNeverHappen(); + this.emitter.emit('inputchange', { bladeController: e, options: t.options, sender: this }); + } + onDescendantLayout_(t) { + this.updatePositions_(), this.emitter.emit('layout', { sender: this }); + } + onDescendantInputChange_(t) { + this.emitter.emit('inputchange', { bladeController: t.bladeController, options: t.options, sender: this }); + } + onDescendantMonitorUpdate_(t) { + this.emitter.emit('monitorupdate', { bladeController: t.bladeController, sender: this }); + } + onBladePositionsChange_() { + this.updatePositions_(); + } + } + class mt extends T { + constructor(t, e) { + super(Object.assign(Object.assign({}, e), { view: new ct(t, { viewName: 'brk', viewProps: e.viewProps }) })), + (this.onRackAdd_ = this.onRackAdd_.bind(this)), + (this.onRackRemove_ = this.onRackRemove_.bind(this)); + const n = new vt(e.root ? void 0 : e.blade); + n.emitter.on('add', this.onRackAdd_), + n.emitter.on('remove', this.onRackRemove_), + (this.rack = n), + this.viewProps.handleDispose(() => { + for (let t = this.rack.children.length - 1; t >= 0; t--) this.rack.children[t].viewProps.set('disposed', !0); + }); + } + onRackAdd_(t) { + t.isRoot && O(this.view.element, t.bladeController.view.element, t.index); + } + onRackRemove_(t) { + t.isRoot && K(t.bladeController.view.element); + } + } + const bt = v('cnt'); + class gt { + constructor(t, e) { + (this.className_ = v(e.viewName || 'fld')), + (this.element = t.createElement('div')), + this.element.classList.add(this.className_(), bt()), + e.viewProps.bindClassModifiers(this.element), + (this.foldable_ = e.foldable), + this.foldable_.bindExpandedClass(this.element, this.className_(void 0, 'expanded')), + g(this.foldable_, 'completed', _(this.element, this.className_(void 0, 'cpl'))); + const n = t.createElement('button'); + n.classList.add(this.className_('b')), + g(e.props, 'title', (t) => { + r(t) + ? this.element.classList.add(this.className_(void 0, 'not')) + : this.element.classList.remove(this.className_(void 0, 'not')); + }), + e.viewProps.bindDisabled(n), + this.element.appendChild(n), + (this.buttonElement = n); + const i = t.createElement('div'); + i.classList.add(this.className_('t')), + f(e.props.value('title'), i), + this.buttonElement.appendChild(i), + (this.titleElement = i); + const s = t.createElement('div'); + s.classList.add(this.className_('m')), this.buttonElement.appendChild(s); + const o = e.containerElement; + o.classList.add(this.className_('c')), this.element.appendChild(o), (this.containerElement = o); + } + } + class _t extends dt { + constructor(t, e) { + var n; + const i = X.create(null === (n = e.expanded) || void 0 === n || n), + s = new mt(t, { blade: e.blade, root: e.root, viewProps: e.viewProps }); + super( + Object.assign(Object.assign({}, e), { + rackController: s, + view: new gt(t, { + containerElement: s.view.element, + foldable: i, + props: e.props, + viewName: e.root ? 'rot' : void 0, + viewProps: e.viewProps + }) + }) + ), + (this.onTitleClick_ = this.onTitleClick_.bind(this)), + (this.props = e.props), + (this.foldable = i), + J(this.foldable, this.view.containerElement), + this.view.buttonElement.addEventListener('click', this.onTitleClick_); + } + get document() { + return this.view.element.ownerDocument; + } + onTitleClick_() { + this.foldable.set('expanded', !this.foldable.get('expanded')); + } + } + const ft = { + id: 'folder', + type: 'blade', + accept(t) { + const e = M, + n = L(t, { title: e.required.string, view: e.required.constant('folder'), expanded: e.optional.boolean }); + return n ? { params: n } : null; + }, + controller: (t) => + new _t(t.document, { + blade: t.blade, + expanded: t.params.expanded, + props: k.fromObject({ title: t.params.title }), + viewProps: t.viewProps + }), + api: (t) => (t.controller instanceof _t ? new pt(t.controller, t.pool) : null) + }; + class wt extends Y { + constructor(t, e) { + const n = e.valueController.viewProps; + super( + Object.assign(Object.assign({}, e), { + value: e.valueController.value, + view: new H(t, { props: e.props, viewProps: n }), + viewProps: n + }) + ), + (this.props = e.props), + (this.valueController = e.valueController), + this.view.valueElement.appendChild(this.valueController.view.element); + } + } + class xt extends e {} + const yt = v('spr'); + class Ct { + constructor(t, e) { + (this.element = t.createElement('div')), this.element.classList.add(yt()), e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('hr'); + n.classList.add(yt('r')), this.element.appendChild(n); + } + } + class Pt extends T { + constructor(t, e) { + super(Object.assign(Object.assign({}, e), { view: new Ct(t, { viewProps: e.viewProps }) })); + } + } + const Et = { + id: 'separator', + type: 'blade', + accept(t) { + const e = L(t, { view: M.required.constant('separator') }); + return e ? { params: e } : null; + }, + controller: (t) => new Pt(t.document, { blade: t.blade, viewProps: t.viewProps }), + api: (t) => (t.controller instanceof Pt ? new xt(t.controller) : null) + }, + kt = v(''); + function Vt(t, e) { + return _(t, kt(void 0, e)); + } + class St extends k { + constructor(t) { + super(t); + } + static create(t) { + var e, n; + const i = null != t ? t : {}, + s = { + disabled: null !== (e = i.disabled) && void 0 !== e && e, + disposed: !1, + hidden: null !== (n = i.hidden) && void 0 !== n && n + }, + o = k.createCore(s); + return new St(o); + } + bindClassModifiers(t) { + g(this, 'disabled', Vt(t, 'disabled')), g(this, 'hidden', Vt(t, 'hidden')); + } + bindDisabled(t) { + g(this, 'disabled', (e) => { + t.disabled = e; + }); + } + bindTabIndex(t) { + g(this, 'disabled', (e) => { + t.tabIndex = e ? -1 : 0; + }); + } + handleDispose(t) { + this.value('disposed').emitter.on('change', (e) => { + e && t(); + }); + } + } + const Mt = v('tbi'); + class Lt { + constructor(t, e) { + (this.element = t.createElement('div')), + this.element.classList.add(Mt()), + e.viewProps.bindClassModifiers(this.element), + g(e.props, 'selected', (t) => { + t ? this.element.classList.add(Mt(void 0, 'sel')) : this.element.classList.remove(Mt(void 0, 'sel')); + }); + const n = t.createElement('button'); + n.classList.add(Mt('b')), e.viewProps.bindDisabled(n), this.element.appendChild(n), (this.buttonElement = n); + const i = t.createElement('div'); + i.classList.add(Mt('t')), f(e.props.value('title'), i), this.buttonElement.appendChild(i), (this.titleElement = i); + } + } + class At { + constructor(t, e) { + (this.emitter = new h()), + (this.onClick_ = this.onClick_.bind(this)), + (this.props = e.props), + (this.viewProps = e.viewProps), + (this.view = new Lt(t, { props: e.props, viewProps: e.viewProps })), + this.view.buttonElement.addEventListener('click', this.onClick_); + } + onClick_() { + this.emitter.emit('click', { sender: this }); + } + } + class It { + constructor(t, e) { + (this.onItemClick_ = this.onItemClick_.bind(this)), + (this.ic_ = new At(t, { props: e.itemProps, viewProps: St.create() })), + this.ic_.emitter.on('click', this.onItemClick_), + (this.cc_ = new mt(t, { blade: W(), viewProps: St.create() })), + (this.props = e.props), + g(this.props, 'selected', (t) => { + this.itemController.props.set('selected', t), this.contentController.viewProps.set('hidden', !t); + }); + } + get itemController() { + return this.ic_; + } + get contentController() { + return this.cc_; + } + onItemClick_() { + this.props.set('selected', !0); + } + } + class Tt { + constructor(t, e) { + (this.controller_ = t), (this.rackApi_ = e); + } + get title() { + var t; + return null !== (t = this.controller_.itemController.props.get('title')) && void 0 !== t ? t : ''; + } + set title(t) { + this.controller_.itemController.props.set('title', t); + } + get selected() { + return this.controller_.props.get('selected'); + } + set selected(t) { + this.controller_.props.set('selected', t); + } + get children() { + return this.rackApi_.children; + } + addButton(t) { + return this.rackApi_.addButton(t); + } + addFolder(t) { + return this.rackApi_.addFolder(t); + } + addSeparator(t) { + return this.rackApi_.addSeparator(t); + } + addTab(t) { + return this.rackApi_.addTab(t); + } + add(t, e) { + this.rackApi_.add(t, e); + } + remove(t) { + this.rackApi_.remove(t); + } + addInput(t, e, n) { + return this.rackApi_.addInput(t, e, n); + } + addMonitor(t, e, n) { + return this.rackApi_.addMonitor(t, e, n); + } + addBlade(t) { + return this.rackApi_.addBlade(t); + } + } + class Dt extends Z { + constructor(t, e) { + super(t, new lt(t.rackController, e)), + (this.onPageAdd_ = this.onPageAdd_.bind(this)), + (this.onPageRemove_ = this.onPageRemove_.bind(this)), + (this.emitter_ = new h()), + (this.pageApiMap_ = new Map()), + this.rackApi_.on('change', (t) => { + this.emitter_.emit('change', { event: t }); + }), + this.rackApi_.on('update', (t) => { + this.emitter_.emit('update', { event: t }); + }), + this.controller_.pageSet.emitter.on('add', this.onPageAdd_), + this.controller_.pageSet.emitter.on('remove', this.onPageRemove_), + this.controller_.pageSet.items.forEach((t) => { + this.setUpPageApi_(t); + }); + } + get pages() { + return this.controller_.pageSet.items.map((t) => { + const e = this.pageApiMap_.get(t); + if (!e) throw p.shouldNeverHappen(); + return e; + }); + } + addPage(t) { + const e = this.controller_.view.element.ownerDocument, + n = new It(e, { itemProps: k.fromObject({ selected: !1, title: t.title }), props: k.fromObject({ selected: !1 }) }); + this.controller_.add(n, t.index); + const i = this.pageApiMap_.get(n); + if (!i) throw p.shouldNeverHappen(); + return i; + } + removePage(t) { + this.controller_.remove(t); + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + setUpPageApi_(t) { + const e = this.rackApi_.apiSet_.find((e) => e.controller_ === t.contentController); + if (!e) throw p.shouldNeverHappen(); + const n = new Tt(t, e); + this.pageApiMap_.set(t, n); + } + onPageAdd_(t) { + this.setUpPageApi_(t.item); + } + onPageRemove_(t) { + if (!this.pageApiMap_.get(t.item)) throw p.shouldNeverHappen(); + this.pageApiMap_.delete(t.item); + } + } + const jt = v('tab'); + class Bt { + constructor(t, e) { + (this.element = t.createElement('div')), + this.element.classList.add(jt(), bt()), + e.viewProps.bindClassModifiers(this.element), + b(e.empty, _(this.element, jt(void 0, 'nop'))); + const n = t.createElement('div'); + n.classList.add(jt('i')), this.element.appendChild(n), (this.itemsElement = n); + const i = e.contentsElement; + i.classList.add(jt('c')), this.element.appendChild(i), (this.contentsElement = i); + } + } + class Rt extends dt { + constructor(t, e) { + const n = new mt(t, { blade: e.blade, viewProps: e.viewProps }), + i = E(!0); + super({ + blade: e.blade, + rackController: n, + view: new Bt(t, { contentsElement: n.view.element, empty: i, viewProps: e.viewProps }) + }), + (this.onPageAdd_ = this.onPageAdd_.bind(this)), + (this.onPageRemove_ = this.onPageRemove_.bind(this)), + (this.onPageSelectedChange_ = this.onPageSelectedChange_.bind(this)), + (this.pageSet_ = new tt(() => null)), + this.pageSet_.emitter.on('add', this.onPageAdd_), + this.pageSet_.emitter.on('remove', this.onPageRemove_), + (this.empty_ = i), + this.applyPages_(); + } + get pageSet() { + return this.pageSet_; + } + add(t, e) { + this.pageSet_.add(t, null != e ? e : this.pageSet_.items.length); + } + remove(t) { + this.pageSet_.remove(this.pageSet_.items[t]); + } + applyPages_() { + this.keepSelection_(), (this.empty_.rawValue = 0 === this.pageSet_.items.length); + } + onPageAdd_(t) { + const e = t.item; + O(this.view.itemsElement, e.itemController.view.element, t.index), + this.rackController.rack.add(e.contentController, t.index), + e.props.value('selected').emitter.on('change', this.onPageSelectedChange_), + this.applyPages_(); + } + onPageRemove_(t) { + const e = t.item; + K(e.itemController.view.element), + this.rackController.rack.remove(e.contentController), + e.props.value('selected').emitter.off('change', this.onPageSelectedChange_), + this.applyPages_(); + } + keepSelection_() { + if (0 === this.pageSet_.items.length) return; + const t = this.pageSet_.items.findIndex((t) => t.props.get('selected')); + t < 0 + ? this.pageSet_.items.forEach((t, e) => { + t.props.set('selected', 0 === e); + }) + : this.pageSet_.items.forEach((e, n) => { + e.props.set('selected', n === t); + }); + } + onPageSelectedChange_(t) { + if (t.rawValue) { + const e = this.pageSet_.items.findIndex((e) => e.props.value('selected') === t.sender); + this.pageSet_.items.forEach((t, n) => { + t.props.set('selected', n === e); + }); + } else this.keepSelection_(); + } + } + const Ft = { + id: 'tab', + type: 'blade', + accept(t) { + const e = M, + n = L(t, { pages: e.required.array(e.required.object({ title: e.required.string })), view: e.required.constant('tab') }); + return n && 0 !== n.pages.length ? { params: n } : null; + }, + controller(t) { + const e = new Rt(t.document, { blade: t.blade, viewProps: t.viewProps }); + return ( + t.params.pages.forEach((n) => { + const i = new It(t.document, { + itemProps: k.fromObject({ selected: !1, title: n.title }), + props: k.fromObject({ selected: !1 }) + }); + e.add(i); + }), + e + ); + }, + api: (t) => (t.controller instanceof Rt ? new Dt(t.controller, t.pool) : null) + }; + class Ut { + constructor() { + (this.disabled = !1), (this.emitter = new h()); + } + dispose() {} + tick() { + this.disabled || this.emitter.emit('tick', { sender: this }); + } + } + class Ot { + constructor(t, e) { + (this.disabled_ = !1), + (this.timerId_ = null), + (this.onTick_ = this.onTick_.bind(this)), + (this.doc_ = t), + (this.emitter = new h()), + (this.interval_ = e), + this.setTimer_(); + } + get disabled() { + return this.disabled_; + } + set disabled(t) { + (this.disabled_ = t), this.disabled_ ? this.clearTimer_() : this.setTimer_(); + } + dispose() { + this.clearTimer_(); + } + clearTimer_() { + if (null === this.timerId_) return; + const t = this.doc_.defaultView; + t && t.clearInterval(this.timerId_), (this.timerId_ = null); + } + setTimer_() { + if ((this.clearTimer_(), this.interval_ <= 0)) return; + const t = this.doc_.defaultView; + t && (this.timerId_ = t.setInterval(this.onTick_, this.interval_)); + } + onTick_() { + this.disabled_ || this.emitter.emit('tick', { sender: this }); + } + } + class Kt { + constructor(t) { + this.constraints = t; + } + constrain(t) { + return this.constraints.reduce((t, e) => e.constrain(t), t); + } + } + function Nt(t, e) { + if (t instanceof e) return t; + if (t instanceof Kt) { + const n = t.constraints.reduce((t, n) => t || (n instanceof e ? n : null), null); + if (n) return n; + } + return null; + } + class $t { + constructor(t) { + this.options = t; + } + constrain(t) { + const e = this.options; + return 0 === e.length || e.filter((e) => e.value === t).length > 0 ? t : e[0].value; + } + } + class zt { + constructor(t) { + (this.maxValue = t.max), (this.minValue = t.min); + } + constrain(t) { + let e = t; + return r(this.minValue) || (e = Math.max(e, this.minValue)), r(this.maxValue) || (e = Math.min(e, this.maxValue)), e; + } + } + class Ht { + constructor(t) { + this.step = t; + } + constrain(t) { + return (t < 0 ? -Math.round(-t / this.step) : Math.round(t / this.step)) * this.step; + } + } + const qt = v('lst'); + class Gt { + constructor(t, e) { + (this.onValueChange_ = this.onValueChange_.bind(this)), + (this.props_ = e.props), + (this.element = t.createElement('div')), + this.element.classList.add(qt()), + e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('select'); + n.classList.add(qt('s')), + g(this.props_, 'options', (e) => { + N(n), + e.forEach((e, i) => { + const s = t.createElement('option'); + (s.dataset.index = String(i)), (s.textContent = e.text), (s.value = String(e.value)), n.appendChild(s); + }); + }), + e.viewProps.bindDisabled(n), + this.element.appendChild(n), + (this.selectElement = n); + const i = t.createElement('div'); + i.classList.add(qt('m')), + i.appendChild(U(t, 'dropdown')), + this.element.appendChild(i), + e.value.emitter.on('change', this.onValueChange_), + (this.value_ = e.value), + this.update_(); + } + update_() { + this.selectElement.value = String(this.value_.rawValue); + } + onValueChange_() { + this.update_(); + } + } + class Yt { + constructor(t, e) { + (this.onSelectChange_ = this.onSelectChange_.bind(this)), + (this.props = e.props), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new Gt(t, { props: this.props, value: this.value, viewProps: this.viewProps })), + this.view.selectElement.addEventListener('change', this.onSelectChange_); + } + onSelectChange_(t) { + const e = t.currentTarget.selectedOptions.item(0); + if (!e) return; + const n = Number(e.dataset.index); + this.value.rawValue = this.props.get('options')[n].value; + } + } + const Wt = v('pop'); + class Xt { + constructor(t, e) { + (this.element = t.createElement('div')), + this.element.classList.add(Wt()), + e.viewProps.bindClassModifiers(this.element), + b(e.shows, _(this.element, Wt(void 0, 'v'))); + } + } + class Qt { + constructor(t, e) { + (this.shows = E(!1)), + (this.viewProps = e.viewProps), + (this.view = new Xt(t, { shows: this.shows, viewProps: this.viewProps })); + } + } + const Jt = v('txt'); + class Zt { + constructor(t, e) { + (this.onChange_ = this.onChange_.bind(this)), + (this.element = t.createElement('div')), + this.element.classList.add(Jt()), + e.viewProps.bindClassModifiers(this.element), + (this.props_ = e.props), + this.props_.emitter.on('change', this.onChange_); + const n = t.createElement('input'); + n.classList.add(Jt('i')), + (n.type = 'text'), + e.viewProps.bindDisabled(n), + this.element.appendChild(n), + (this.inputElement = n), + e.value.emitter.on('change', this.onChange_), + (this.value_ = e.value), + this.refresh(); + } + refresh() { + const t = this.props_.get('formatter'); + this.inputElement.value = t(this.value_.rawValue); + } + onChange_() { + this.refresh(); + } + } + class te { + constructor(t, e) { + (this.onInputChange_ = this.onInputChange_.bind(this)), + (this.parser_ = e.parser), + (this.props = e.props), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new Zt(t, { props: e.props, value: this.value, viewProps: this.viewProps })), + this.view.inputElement.addEventListener('change', this.onInputChange_); + } + onInputChange_(t) { + const e = t.currentTarget.value, + n = this.parser_(e); + r(n) || (this.value.rawValue = n), this.view.refresh(); + } + } + function ee(t) { + return 'false' !== t && !!t; + } + function ne(t) { + return (function (t) { + return String(t); + })(t); + } + class ie { + constructor(t) { + this.text = t; + } + evaluate() { + return Number(this.text); + } + toString() { + return this.text; + } + } + const se = { + '**': (t, e) => Math.pow(t, e), + '*': (t, e) => t * e, + '/': (t, e) => t / e, + '%': (t, e) => t % e, + '+': (t, e) => t + e, + '-': (t, e) => t - e, + '<<': (t, e) => t << e, + '>>': (t, e) => t >> e, + '>>>': (t, e) => t >>> e, + '&': (t, e) => t & e, + '^': (t, e) => t ^ e, + '|': (t, e) => t | e + }; + class oe { + constructor(t, e, n) { + (this.left = e), (this.operator = t), (this.right = n); + } + evaluate() { + const t = se[this.operator]; + if (!t) throw new Error(`unexpected binary operator: '${this.operator}`); + return t(this.left.evaluate(), this.right.evaluate()); + } + toString() { + return ['b(', this.left.toString(), this.operator, this.right.toString(), ')'].join(' '); + } + } + const re = { '+': (t) => t, '-': (t) => -t, '~': (t) => ~t }; + class ae { + constructor(t, e) { + (this.operator = t), (this.expression = e); + } + evaluate() { + const t = re[this.operator]; + if (!t) throw new Error(`unexpected unary operator: '${this.operator}`); + return t(this.expression.evaluate()); + } + toString() { + return ['u(', this.operator, this.expression.toString(), ')'].join(' '); + } + } + function le(t) { + return (e, n) => { + for (let i = 0; i < t.length; i++) { + const s = t[i](e, n); + if ('' !== s) return s; + } + return ''; + }; + } + function pe(t, e) { + var n; + const i = t.substr(e).match(/^\s+/); + return null !== (n = i && i[0]) && void 0 !== n ? n : ''; + } + function de(t, e) { + var n; + const i = t.substr(e).match(/^[0-9]+/); + return null !== (n = i && i[0]) && void 0 !== n ? n : ''; + } + function ce(t, e) { + const n = t.substr(e, 1); + if (((e += 1), 'e' !== n.toLowerCase())) return ''; + const i = (function (t, e) { + const n = de(t, e); + if ('' !== n) return n; + const i = t.substr(e, 1); + if ('-' !== i && '+' !== i) return ''; + const s = de(t, (e += 1)); + return '' === s ? '' : i + s; + })(t, e); + return '' === i ? '' : n + i; + } + function he(t, e) { + const n = t.substr(e, 1); + if ('0' === n) return n; + const i = (function (t, e) { + const n = t.substr(e, 1); + return n.match(/^[1-9]$/) ? n : ''; + })(t, e); + return (e += i.length), '' === i ? '' : i + de(t, e); + } + const ue = le([ + function (t, e) { + const n = he(t, e); + if (((e += n.length), '' === n)) return ''; + const i = t.substr(e, 1); + if (((e += i.length), '.' !== i)) return ''; + const s = de(t, e); + return n + i + s + ce(t, (e += s.length)); + }, + function (t, e) { + const n = t.substr(e, 1); + if (((e += n.length), '.' !== n)) return ''; + const i = de(t, e); + return (e += i.length), '' === i ? '' : n + i + ce(t, e); + }, + function (t, e) { + const n = he(t, e); + return (e += n.length), '' === n ? '' : n + ce(t, e); + } + ]); + const ve = le([ + function (t, e) { + const n = t.substr(e, 2); + if (((e += n.length), '0b' !== n.toLowerCase())) return ''; + const i = (function (t, e) { + var n; + const i = t.substr(e).match(/^[01]+/); + return null !== (n = i && i[0]) && void 0 !== n ? n : ''; + })(t, e); + return '' === i ? '' : n + i; + }, + function (t, e) { + const n = t.substr(e, 2); + if (((e += n.length), '0o' !== n.toLowerCase())) return ''; + const i = (function (t, e) { + var n; + const i = t.substr(e).match(/^[0-7]+/); + return null !== (n = i && i[0]) && void 0 !== n ? n : ''; + })(t, e); + return '' === i ? '' : n + i; + }, + function (t, e) { + const n = t.substr(e, 2); + if (((e += n.length), '0x' !== n.toLowerCase())) return ''; + const i = (function (t, e) { + var n; + const i = t.substr(e).match(/^[0-9a-f]+/i); + return null !== (n = i && i[0]) && void 0 !== n ? n : ''; + })(t, e); + return '' === i ? '' : n + i; + } + ]), + me = le([ve, ue]); + function be(t, e) { + return ( + (function (t, e) { + const n = me(t, e); + return (e += n.length), '' === n ? null : { evaluable: new ie(n), cursor: e }; + })(t, e) || + (function (t, e) { + const n = t.substr(e, 1); + if (((e += n.length), '(' !== n)) return null; + const i = fe(t, e); + if (!i) return null; + (e = i.cursor), (e += pe(t, e).length); + const s = t.substr(e, 1); + return (e += s.length), ')' !== s ? null : { evaluable: i.evaluable, cursor: e }; + })(t, e) + ); + } + function ge(t, e, n) { + n += pe(e, n).length; + const i = t.filter((t) => e.startsWith(t, n))[0]; + return i ? ((n += i.length), { cursor: (n += pe(e, n).length), operator: i }) : null; + } + const _e = [['**'], ['*', '/', '%'], ['+', '-'], ['<<', '>>>', '>>'], ['&'], ['^'], ['|']].reduce( + (t, e) => + (function (t, e) { + return (n, i) => { + const s = t(n, i); + if (!s) return null; + i = s.cursor; + let o = s.evaluable; + for (;;) { + const s = ge(e, n, i); + if (!s) break; + i = s.cursor; + const r = t(n, i); + if (!r) return null; + (i = r.cursor), (o = new oe(s.operator, o, r.evaluable)); + } + return o ? { cursor: i, evaluable: o } : null; + }; + })(t, e), + function t(e, n) { + const i = be(e, n); + if (i) return i; + const s = e.substr(n, 1); + if (((n += s.length), '+' !== s && '-' !== s && '~' !== s)) return null; + const o = t(e, n); + return o ? { cursor: (n = o.cursor), evaluable: new ae(s, o.evaluable) } : null; + } + ); + function fe(t, e) { + return (e += pe(t, e).length), _e(t, e); + } + function we(t) { + var e; + const n = (function (t) { + const e = fe(t, 0); + return e ? (e.cursor + pe(t, e.cursor).length !== t.length ? null : e.evaluable) : null; + })(t); + return null !== (e = null == n ? void 0 : n.evaluate()) && void 0 !== e ? e : null; + } + function xe(t) { + if ('number' == typeof t) return t; + if ('string' == typeof t) { + const e = we(t); + if (!r(e)) return e; + } + return 0; + } + function ye(t) { + return String(t); + } + function Ce(t) { + return (e) => e.toFixed(Math.max(Math.min(t, 20), 0)); + } + const Pe = Ce(0); + function Ee(t) { + return Pe(t) + '%'; + } + function ke(t) { + return String(t); + } + function Ve(t) { + return t; + } + function Se(t, e) { + for (; t.length < e; ) t.push(void 0); + } + function Me(t) { + const e = []; + return Se(e, t), E(e); + } + function Le(t) { + const e = t.indexOf(void 0); + return e < 0 ? t : t.slice(0, e); + } + function Ae({ primary: t, secondary: e, forward: n, backward: i }) { + let s = !1; + function o(t) { + s || ((s = !0), t(), (s = !1)); + } + t.emitter.on('change', (i) => { + o(() => { + e.setRawValue(n(t, e), i.options); + }); + }), + e.emitter.on('change', (s) => { + o(() => { + t.setRawValue(i(t, e), s.options); + }), + o(() => { + e.setRawValue(n(t, e), s.options); + }); + }), + o(() => { + e.setRawValue(n(t, e), { forceEmit: !1, last: !0 }); + }); + } + function Ie(t, e) { + const n = t * (e.altKey ? 0.1 : 1) * (e.shiftKey ? 10 : 1); + return e.upKey ? +n : e.downKey ? -n : 0; + } + function Te(t) { + return { altKey: t.altKey, downKey: 'ArrowDown' === t.key, shiftKey: t.shiftKey, upKey: 'ArrowUp' === t.key }; + } + function De(t) { + return { altKey: t.altKey, downKey: 'ArrowLeft' === t.key, shiftKey: t.shiftKey, upKey: 'ArrowRight' === t.key }; + } + function je(t) { + return ( + (function (t) { + return 'ArrowUp' === t || 'ArrowDown' === t; + })(t) || + 'ArrowLeft' === t || + 'ArrowRight' === t + ); + } + function Be(t, e) { + const n = e.ownerDocument.defaultView, + i = e.getBoundingClientRect(); + return { x: t.pageX - (((n && n.scrollX) || 0) + i.left), y: t.pageY - (((n && n.scrollY) || 0) + i.top) }; + } + class Re { + constructor(t) { + (this.lastTouch_ = null), + (this.onDocumentMouseMove_ = this.onDocumentMouseMove_.bind(this)), + (this.onDocumentMouseUp_ = this.onDocumentMouseUp_.bind(this)), + (this.onMouseDown_ = this.onMouseDown_.bind(this)), + (this.onTouchEnd_ = this.onTouchEnd_.bind(this)), + (this.onTouchMove_ = this.onTouchMove_.bind(this)), + (this.onTouchStart_ = this.onTouchStart_.bind(this)), + (this.elem_ = t), + (this.emitter = new h()), + t.addEventListener('touchstart', this.onTouchStart_, { passive: !1 }), + t.addEventListener('touchmove', this.onTouchMove_, { passive: !0 }), + t.addEventListener('touchend', this.onTouchEnd_), + t.addEventListener('mousedown', this.onMouseDown_); + } + computePosition_(t) { + const e = this.elem_.getBoundingClientRect(); + return { bounds: { width: e.width, height: e.height }, point: t ? { x: t.x, y: t.y } : null }; + } + onMouseDown_(t) { + var e; + t.preventDefault(), null === (e = t.currentTarget) || void 0 === e || e.focus(); + const n = this.elem_.ownerDocument; + n.addEventListener('mousemove', this.onDocumentMouseMove_), + n.addEventListener('mouseup', this.onDocumentMouseUp_), + this.emitter.emit('down', { + altKey: t.altKey, + data: this.computePosition_(Be(t, this.elem_)), + sender: this, + shiftKey: t.shiftKey + }); + } + onDocumentMouseMove_(t) { + this.emitter.emit('move', { + altKey: t.altKey, + data: this.computePosition_(Be(t, this.elem_)), + sender: this, + shiftKey: t.shiftKey + }); + } + onDocumentMouseUp_(t) { + const e = this.elem_.ownerDocument; + e.removeEventListener('mousemove', this.onDocumentMouseMove_), + e.removeEventListener('mouseup', this.onDocumentMouseUp_), + this.emitter.emit('up', { + altKey: t.altKey, + data: this.computePosition_(Be(t, this.elem_)), + sender: this, + shiftKey: t.shiftKey + }); + } + onTouchStart_(t) { + t.preventDefault(); + const e = t.targetTouches.item(0), + n = this.elem_.getBoundingClientRect(); + this.emitter.emit('down', { + altKey: t.altKey, + data: this.computePosition_(e ? { x: e.clientX - n.left, y: e.clientY - n.top } : void 0), + sender: this, + shiftKey: t.shiftKey + }), + (this.lastTouch_ = e); + } + onTouchMove_(t) { + const e = t.targetTouches.item(0), + n = this.elem_.getBoundingClientRect(); + this.emitter.emit('move', { + altKey: t.altKey, + data: this.computePosition_(e ? { x: e.clientX - n.left, y: e.clientY - n.top } : void 0), + sender: this, + shiftKey: t.shiftKey + }), + (this.lastTouch_ = e); + } + onTouchEnd_(t) { + var e; + const n = null !== (e = t.targetTouches.item(0)) && void 0 !== e ? e : this.lastTouch_, + i = this.elem_.getBoundingClientRect(); + this.emitter.emit('up', { + altKey: t.altKey, + data: this.computePosition_(n ? { x: n.clientX - i.left, y: n.clientY - i.top } : void 0), + sender: this, + shiftKey: t.shiftKey + }); + } + } + function Fe(t, e, n, i, s) { + return i + ((t - e) / (n - e)) * (s - i); + } + function Ue(t) { + return String(t.toFixed(10)).split('.')[1].replace(/0+$/, '').length; + } + function Oe(t, e, n) { + return Math.min(Math.max(t, e), n); + } + function Ke(t, e) { + return ((t % e) + e) % e; + } + const Ne = v('txt'); + class $e { + constructor(t, e) { + (this.onChange_ = this.onChange_.bind(this)), + (this.props_ = e.props), + this.props_.emitter.on('change', this.onChange_), + (this.element = t.createElement('div')), + this.element.classList.add(Ne(), Ne(void 0, 'num')), + e.arrayPosition && this.element.classList.add(Ne(void 0, e.arrayPosition)), + e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('input'); + n.classList.add(Ne('i')), + (n.type = 'text'), + e.viewProps.bindDisabled(n), + this.element.appendChild(n), + (this.inputElement = n), + (this.onDraggingChange_ = this.onDraggingChange_.bind(this)), + (this.dragging_ = e.dragging), + this.dragging_.emitter.on('change', this.onDraggingChange_), + this.element.classList.add(Ne()), + this.inputElement.classList.add(Ne('i')); + const i = t.createElement('div'); + i.classList.add(Ne('k')), this.element.appendChild(i), (this.knobElement = i); + const s = t.createElementNS(D, 'svg'); + s.classList.add(Ne('g')), this.knobElement.appendChild(s); + const o = t.createElementNS(D, 'path'); + o.classList.add(Ne('gb')), s.appendChild(o), (this.guideBodyElem_ = o); + const r = t.createElementNS(D, 'path'); + r.classList.add(Ne('gh')), s.appendChild(r), (this.guideHeadElem_ = r); + const a = t.createElement('div'); + a.classList.add(v('tt')()), + this.knobElement.appendChild(a), + (this.tooltipElem_ = a), + e.value.emitter.on('change', this.onChange_), + (this.value = e.value), + this.refresh(); + } + onDraggingChange_(t) { + if (null === t.rawValue) return void this.element.classList.remove(Ne(void 0, 'drg')); + this.element.classList.add(Ne(void 0, 'drg')); + const e = t.rawValue / this.props_.get('draggingScale'), + n = e + (e > 0 ? -1 : e < 0 ? 1 : 0), + i = Oe(-n, -4, 4); + this.guideHeadElem_.setAttributeNS(null, 'd', [`M ${n + i},0 L${n},4 L${n + i},8`, `M ${e},-1 L${e},9`].join(' ')), + this.guideBodyElem_.setAttributeNS(null, 'd', `M 0,4 L${e},4`); + const s = this.props_.get('formatter'); + (this.tooltipElem_.textContent = s(this.value.rawValue)), (this.tooltipElem_.style.left = `${e}px`); + } + refresh() { + const t = this.props_.get('formatter'); + this.inputElement.value = t(this.value.rawValue); + } + onChange_() { + this.refresh(); + } + } + class ze { + constructor(t, e) { + (this.originRawValue_ = 0), + (this.onInputChange_ = this.onInputChange_.bind(this)), + (this.onInputKeyDown_ = this.onInputKeyDown_.bind(this)), + (this.onInputKeyUp_ = this.onInputKeyUp_.bind(this)), + (this.onPointerDown_ = this.onPointerDown_.bind(this)), + (this.onPointerMove_ = this.onPointerMove_.bind(this)), + (this.onPointerUp_ = this.onPointerUp_.bind(this)), + (this.baseStep_ = e.baseStep), + (this.parser_ = e.parser), + (this.props = e.props), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.dragging_ = E(null)), + (this.view = new $e(t, { + arrayPosition: e.arrayPosition, + dragging: this.dragging_, + props: this.props, + value: this.value, + viewProps: this.viewProps + })), + this.view.inputElement.addEventListener('change', this.onInputChange_), + this.view.inputElement.addEventListener('keydown', this.onInputKeyDown_), + this.view.inputElement.addEventListener('keyup', this.onInputKeyUp_); + const n = new Re(this.view.knobElement); + n.emitter.on('down', this.onPointerDown_), n.emitter.on('move', this.onPointerMove_), n.emitter.on('up', this.onPointerUp_); + } + onInputChange_(t) { + const e = t.currentTarget.value, + n = this.parser_(e); + r(n) || (this.value.rawValue = n), this.view.refresh(); + } + onInputKeyDown_(t) { + const e = Ie(this.baseStep_, Te(t)); + 0 !== e && this.value.setRawValue(this.value.rawValue + e, { forceEmit: !1, last: !1 }); + } + onInputKeyUp_(t) { + 0 !== Ie(this.baseStep_, Te(t)) && this.value.setRawValue(this.value.rawValue, { forceEmit: !0, last: !0 }); + } + onPointerDown_() { + (this.originRawValue_ = this.value.rawValue), (this.dragging_.rawValue = 0); + } + computeDraggingValue_(t) { + if (!t.point) return null; + const e = t.point.x - t.bounds.width / 2; + return this.originRawValue_ + e * this.props.get('draggingScale'); + } + onPointerMove_(t) { + const e = this.computeDraggingValue_(t.data); + null !== e && + (this.value.setRawValue(e, { forceEmit: !1, last: !1 }), + (this.dragging_.rawValue = this.value.rawValue - this.originRawValue_)); + } + onPointerUp_(t) { + const e = this.computeDraggingValue_(t.data); + null !== e && (this.value.setRawValue(e, { forceEmit: !0, last: !0 }), (this.dragging_.rawValue = null)); + } + } + const He = v('sld'); + class qe { + constructor(t, e) { + (this.onChange_ = this.onChange_.bind(this)), + (this.props_ = e.props), + this.props_.emitter.on('change', this.onChange_), + (this.element = t.createElement('div')), + this.element.classList.add(He()), + e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('div'); + n.classList.add(He('t')), e.viewProps.bindTabIndex(n), this.element.appendChild(n), (this.trackElement = n); + const i = t.createElement('div'); + i.classList.add(He('k')), + this.trackElement.appendChild(i), + (this.knobElement = i), + e.value.emitter.on('change', this.onChange_), + (this.value = e.value), + this.update_(); + } + update_() { + const t = Oe(Fe(this.value.rawValue, this.props_.get('minValue'), this.props_.get('maxValue'), 0, 100), 0, 100); + this.knobElement.style.width = `${t}%`; + } + onChange_() { + this.update_(); + } + } + class Ge { + constructor(t, e) { + (this.onKeyDown_ = this.onKeyDown_.bind(this)), + (this.onKeyUp_ = this.onKeyUp_.bind(this)), + (this.onPointerDownOrMove_ = this.onPointerDownOrMove_.bind(this)), + (this.onPointerUp_ = this.onPointerUp_.bind(this)), + (this.baseStep_ = e.baseStep), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.props = e.props), + (this.view = new qe(t, { props: this.props, value: this.value, viewProps: this.viewProps })), + (this.ptHandler_ = new Re(this.view.trackElement)), + this.ptHandler_.emitter.on('down', this.onPointerDownOrMove_), + this.ptHandler_.emitter.on('move', this.onPointerDownOrMove_), + this.ptHandler_.emitter.on('up', this.onPointerUp_), + this.view.trackElement.addEventListener('keydown', this.onKeyDown_), + this.view.trackElement.addEventListener('keyup', this.onKeyUp_); + } + handlePointerEvent_(t, e) { + t.point && + this.value.setRawValue( + Fe(Oe(t.point.x, 0, t.bounds.width), 0, t.bounds.width, this.props.get('minValue'), this.props.get('maxValue')), + e + ); + } + onPointerDownOrMove_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerUp_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !0, last: !0 }); + } + onKeyDown_(t) { + const e = Ie(this.baseStep_, De(t)); + 0 !== e && this.value.setRawValue(this.value.rawValue + e, { forceEmit: !1, last: !1 }); + } + onKeyUp_(t) { + 0 !== Ie(this.baseStep_, De(t)) && this.value.setRawValue(this.value.rawValue, { forceEmit: !0, last: !0 }); + } + } + const Ye = v('sldtxt'); + class We { + constructor(t, e) { + (this.element = t.createElement('div')), this.element.classList.add(Ye()); + const n = t.createElement('div'); + n.classList.add(Ye('s')), + (this.sliderView_ = e.sliderView), + n.appendChild(this.sliderView_.element), + this.element.appendChild(n); + const i = t.createElement('div'); + i.classList.add(Ye('t')), (this.textView_ = e.textView), i.appendChild(this.textView_.element), this.element.appendChild(i); + } + } + class Xe { + constructor(t, e) { + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.sliderC_ = new Ge(t, { baseStep: e.baseStep, props: e.sliderProps, value: e.value, viewProps: this.viewProps })), + (this.textC_ = new ze(t, { + baseStep: e.baseStep, + parser: e.parser, + props: e.textProps, + value: e.value, + viewProps: e.viewProps + })), + (this.view = new We(t, { sliderView: this.sliderC_.view, textView: this.textC_.view })); + } + get sliderController() { + return this.sliderC_; + } + get textController() { + return this.textC_; + } + } + function Qe(t, e) { + t.write(e); + } + function Je(t) { + const e = M; + return Array.isArray(t) + ? e.required.array(e.required.object({ text: e.required.string, value: e.required.raw }))(t).value + : 'object' == typeof t + ? e.required.raw(t).value + : void 0; + } + function Ze(t) { + if ('inline' === t || 'popup' === t) return t; + } + function tn(t) { + const e = M; + return e.required.object({ max: e.optional.number, min: e.optional.number, step: e.optional.number })(t).value; + } + function en(t) { + if (Array.isArray(t)) return t; + const e = []; + return ( + Object.keys(t).forEach((n) => { + e.push({ text: n, value: t[n] }); + }), + e + ); + } + function nn(t) { + return r(t) ? null : new $t(en(t)); + } + function sn(t) { + const e = t ? Nt(t, $t) : null; + return e ? e.options : null; + } + function on(t, e) { + const n = t && Nt(t, Ht); + return n ? Ue(n.step) : Math.max(Ue(e), 2); + } + function rn(t) { + const e = (function (t) { + const e = t ? Nt(t, Ht) : null; + return e ? e.step : null; + })(t); + return null != e ? e : 1; + } + function an(t, e) { + var n; + const i = t && Nt(t, Ht), + s = Math.abs(null !== (n = null == i ? void 0 : i.step) && void 0 !== n ? n : e); + return 0 === s ? 0.1 : Math.pow(10, Math.floor(Math.log10(s)) - 1); + } + const ln = v('ckb'); + class pn { + constructor(t, e) { + (this.onValueChange_ = this.onValueChange_.bind(this)), + (this.element = t.createElement('div')), + this.element.classList.add(ln()), + e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('label'); + n.classList.add(ln('l')), this.element.appendChild(n); + const i = t.createElement('input'); + i.classList.add(ln('i')), + (i.type = 'checkbox'), + n.appendChild(i), + (this.inputElement = i), + e.viewProps.bindDisabled(this.inputElement); + const s = t.createElement('div'); + s.classList.add(ln('w')), n.appendChild(s); + const o = U(t, 'check'); + s.appendChild(o), e.value.emitter.on('change', this.onValueChange_), (this.value = e.value), this.update_(); + } + update_() { + this.inputElement.checked = this.value.rawValue; + } + onValueChange_() { + this.update_(); + } + } + class dn { + constructor(t, e) { + (this.onInputChange_ = this.onInputChange_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new pn(t, { value: this.value, viewProps: this.viewProps })), + this.view.inputElement.addEventListener('change', this.onInputChange_); + } + onInputChange_(t) { + const e = t.currentTarget; + this.value.rawValue = e.checked; + } + } + const cn = { + id: 'input-bool', + type: 'input', + accept: (t, e) => { + if ('boolean' != typeof t) return null; + const n = L(e, { options: M.optional.custom(Je) }); + return n ? { initialValue: t, params: n } : null; + }, + binding: { + reader: (t) => ee, + constraint: (t) => + (function (t) { + const e = [], + n = nn(t.options); + return n && e.push(n), new Kt(e); + })(t.params), + writer: (t) => Qe + }, + controller: (t) => { + var e; + const n = t.document, + i = t.value, + s = t.constraint; + return s && Nt(s, $t) + ? new Yt(n, { + props: k.fromObject({ options: null !== (e = sn(s)) && void 0 !== e ? e : [] }), + value: i, + viewProps: t.viewProps + }) + : new dn(n, { value: i, viewProps: t.viewProps }); + } + }, + hn = v('col'); + class un { + constructor(t, e) { + (this.element = t.createElement('div')), + this.element.classList.add(hn()), + e.foldable.bindExpandedClass(this.element, hn(void 0, 'expanded')), + g(e.foldable, 'completed', _(this.element, hn(void 0, 'cpl'))); + const n = t.createElement('div'); + n.classList.add(hn('h')), this.element.appendChild(n); + const i = t.createElement('div'); + i.classList.add(hn('s')), n.appendChild(i), (this.swatchElement = i); + const s = t.createElement('div'); + if ((s.classList.add(hn('t')), n.appendChild(s), (this.textElement = s), 'inline' === e.pickerLayout)) { + const e = t.createElement('div'); + e.classList.add(hn('p')), this.element.appendChild(e), (this.pickerElement = e); + } else this.pickerElement = null; + } + } + function vn(t, e, n) { + const i = Ke(t, 360), + s = Oe(e / 100, 0, 1), + o = Oe(n / 100, 0, 1), + r = o * s, + a = r * (1 - Math.abs(((i / 60) % 2) - 1)), + l = o - r; + let p, d, c; + return ( + ([p, d, c] = + i >= 0 && i < 60 + ? [r, a, 0] + : i >= 60 && i < 120 + ? [a, r, 0] + : i >= 120 && i < 180 + ? [0, r, a] + : i >= 180 && i < 240 + ? [0, a, r] + : i >= 240 && i < 300 + ? [a, 0, r] + : [r, 0, a]), + [255 * (p + l), 255 * (d + l), 255 * (c + l)] + ); + } + function mn(t) { + return [t[0], t[1], t[2]]; + } + function bn(t, e) { + return [t[0], t[1], t[2], e]; + } + const gn = { + hsl: { + hsl: (t, e, n) => [t, e, n], + hsv: function (t, e, n) { + const i = n + (e * (100 - Math.abs(2 * n - 100))) / 200; + return [t, 0 !== i ? (e * (100 - Math.abs(2 * n - 100))) / i : 0, n + (e * (100 - Math.abs(2 * n - 100))) / 200]; + }, + rgb: function (t, e, n) { + const i = ((t % 360) + 360) % 360, + s = Oe(e / 100, 0, 1), + o = Oe(n / 100, 0, 1), + r = (1 - Math.abs(2 * o - 1)) * s, + a = r * (1 - Math.abs(((i / 60) % 2) - 1)), + l = o - r / 2; + let p, d, c; + return ( + ([p, d, c] = + i >= 0 && i < 60 + ? [r, a, 0] + : i >= 60 && i < 120 + ? [a, r, 0] + : i >= 120 && i < 180 + ? [0, r, a] + : i >= 180 && i < 240 + ? [0, a, r] + : i >= 240 && i < 300 + ? [a, 0, r] + : [r, 0, a]), + [255 * (p + l), 255 * (d + l), 255 * (c + l)] + ); + } + }, + hsv: { + hsl: function (t, e, n) { + const i = 100 - Math.abs((n * (200 - e)) / 100 - 100); + return [t, 0 !== i ? (e * n) / i : 0, (n * (200 - e)) / 200]; + }, + hsv: (t, e, n) => [t, e, n], + rgb: vn + }, + rgb: { + hsl: function (t, e, n) { + const i = Oe(t / 255, 0, 1), + s = Oe(e / 255, 0, 1), + o = Oe(n / 255, 0, 1), + r = Math.max(i, s, o), + a = Math.min(i, s, o), + l = r - a; + let p = 0, + d = 0; + const c = (a + r) / 2; + return ( + 0 !== l && + ((d = l / (1 - Math.abs(r + a - 1))), + (p = i === r ? (s - o) / l : s === r ? 2 + (o - i) / l : 4 + (i - s) / l), + (p = p / 6 + (p < 0 ? 1 : 0))), + [360 * p, 100 * d, 100 * c] + ); + }, + hsv: function (t, e, n) { + const i = Oe(t / 255, 0, 1), + s = Oe(e / 255, 0, 1), + o = Oe(n / 255, 0, 1), + r = Math.max(i, s, o), + a = r - Math.min(i, s, o); + let l; + return ( + (l = + 0 === a + ? 0 + : r === i + ? (((((s - o) / a) % 6) + 6) % 6) * 60 + : r === s + ? 60 * ((o - i) / a + 2) + : 60 * ((i - s) / a + 4)), + [l, 100 * (0 === r ? 0 : a / r), 100 * r] + ); + }, + rgb: (t, e, n) => [t, e, n] + } + }; + const _n = { + hsl: (t) => { + var e; + return [Ke(t[0], 360), Oe(t[1], 0, 100), Oe(t[2], 0, 100), Oe(null !== (e = t[3]) && void 0 !== e ? e : 1, 0, 1)]; + }, + hsv: (t) => { + var e; + return [Ke(t[0], 360), Oe(t[1], 0, 100), Oe(t[2], 0, 100), Oe(null !== (e = t[3]) && void 0 !== e ? e : 1, 0, 1)]; + }, + rgb: (t) => { + var e; + return [Oe(t[0], 0, 255), Oe(t[1], 0, 255), Oe(t[2], 0, 255), Oe(null !== (e = t[3]) && void 0 !== e ? e : 1, 0, 1)]; + } + }; + function fn(t, e) { + return 'object' == typeof t && !r(t) && e in t && 'number' == typeof t[e]; + } + class wn { + constructor(t, e) { + (this.mode_ = e), (this.comps_ = _n[e](t)); + } + static black() { + return new wn([0, 0, 0], 'rgb'); + } + static fromObject(t) { + const e = 'a' in t ? [t.r, t.g, t.b, t.a] : [t.r, t.g, t.b]; + return new wn(e, 'rgb'); + } + static toRgbaObject(t) { + return t.toRgbaObject(); + } + static isRgbColorObject(t) { + return fn(t, 'r') && fn(t, 'g') && fn(t, 'b'); + } + static isRgbaColorObject(t) { + return this.isRgbColorObject(t) && fn(t, 'a'); + } + static isColorObject(t) { + return this.isRgbColorObject(t); + } + static equals(t, e) { + if (t.mode_ !== e.mode_) return !1; + const n = t.comps_, + i = e.comps_; + for (let t = 0; t < n.length; t++) if (n[t] !== i[t]) return !1; + return !0; + } + get mode() { + return this.mode_; + } + getComponents(t) { + return bn(((e = mn(this.comps_)), (n = this.mode_), (i = t || this.mode_), gn[n][i](...e)), this.comps_[3]); + var e, n, i; + } + toRgbaObject() { + const t = this.getComponents('rgb'); + return { r: t[0], g: t[1], b: t[2], a: t[3] }; + } + } + const xn = v('colp'); + class yn { + constructor(t, e) { + (this.alphaViews_ = null), (this.element = t.createElement('div')), this.element.classList.add(xn()); + const n = t.createElement('div'); + n.classList.add(xn('hsv')); + const i = t.createElement('div'); + i.classList.add(xn('sv')), + (this.svPaletteView_ = e.svPaletteView), + i.appendChild(this.svPaletteView_.element), + n.appendChild(i); + const s = t.createElement('div'); + s.classList.add(xn('h')), + (this.hPaletteView_ = e.hPaletteView), + s.appendChild(this.hPaletteView_.element), + n.appendChild(s), + this.element.appendChild(n); + const o = t.createElement('div'); + if ( + (o.classList.add(xn('rgb')), + (this.textView_ = e.textView), + o.appendChild(this.textView_.element), + this.element.appendChild(o), + e.alphaViews) + ) { + this.alphaViews_ = { palette: e.alphaViews.palette, text: e.alphaViews.text }; + const n = t.createElement('div'); + n.classList.add(xn('a')); + const i = t.createElement('div'); + i.classList.add(xn('ap')), i.appendChild(this.alphaViews_.palette.element), n.appendChild(i); + const s = t.createElement('div'); + s.classList.add(xn('at')), s.appendChild(this.alphaViews_.text.element), n.appendChild(s), this.element.appendChild(n); + } + } + get allFocusableElements() { + const t = [ + this.svPaletteView_.element, + this.hPaletteView_.element, + this.textView_.modeSelectElement, + ...this.textView_.textViews.map((t) => t.inputElement) + ]; + return this.alphaViews_ && t.push(this.alphaViews_.palette.element, this.alphaViews_.text.inputElement), t; + } + } + function Cn(t) { + const e = M; + return L(t, { alpha: e.optional.boolean, expanded: e.optional.boolean, picker: e.optional.custom(Ze) }); + } + function Pn(t) { + return t ? 0.1 : 1; + } + function En(t, e) { + const n = t.match(/^(.+)%$/); + return n ? Math.min(0.01 * parseFloat(n[1]) * e, e) : Math.min(parseFloat(t), e); + } + const kn = { deg: (t) => t, grad: (t) => (360 * t) / 400, rad: (t) => (360 * t) / (2 * Math.PI), turn: (t) => 360 * t }; + function Vn(t) { + const e = t.match(/^([0-9.]+?)(deg|grad|rad|turn)$/); + if (!e) return parseFloat(t); + const n = parseFloat(e[1]), + i = e[2]; + return kn[i](n); + } + const Sn = { + 'func.rgb': (t) => { + const e = t.match(/^rgb\(\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/); + if (!e) return null; + const n = [En(e[1], 255), En(e[2], 255), En(e[3], 255)]; + return isNaN(n[0]) || isNaN(n[1]) || isNaN(n[2]) ? null : new wn(n, 'rgb'); + }, + 'func.rgba': (t) => { + const e = t.match( + /^rgba\(\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/ + ); + if (!e) return null; + const n = [En(e[1], 255), En(e[2], 255), En(e[3], 255), En(e[4], 1)]; + return isNaN(n[0]) || isNaN(n[1]) || isNaN(n[2]) || isNaN(n[3]) ? null : new wn(n, 'rgb'); + }, + 'func.hsl': (t) => { + const e = t.match(/^hsl\(\s*([0-9A-Fa-f.]+(?:deg|grad|rad|turn)?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/); + if (!e) return null; + const n = [Vn(e[1]), En(e[2], 100), En(e[3], 100)]; + return isNaN(n[0]) || isNaN(n[1]) || isNaN(n[2]) ? null : new wn(n, 'hsl'); + }, + 'func.hsla': (t) => { + const e = t.match( + /^hsla\(\s*([0-9A-Fa-f.]+(?:deg|grad|rad|turn)?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*,\s*([0-9A-Fa-f.]+%?)\s*\)$/ + ); + if (!e) return null; + const n = [Vn(e[1]), En(e[2], 100), En(e[3], 100), En(e[4], 1)]; + return isNaN(n[0]) || isNaN(n[1]) || isNaN(n[2]) || isNaN(n[3]) ? null : new wn(n, 'hsl'); + }, + 'hex.rgb': (t) => { + const e = t.match(/^#([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$/); + if (e) return new wn([parseInt(e[1] + e[1], 16), parseInt(e[2] + e[2], 16), parseInt(e[3] + e[3], 16)], 'rgb'); + const n = t.match(/^(?:#|0x)([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/); + return n ? new wn([parseInt(n[1], 16), parseInt(n[2], 16), parseInt(n[3], 16)], 'rgb') : null; + }, + 'hex.rgba': (t) => { + const e = t.match(/^#?([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$/); + if (e) + return new wn( + [ + parseInt(e[1] + e[1], 16), + parseInt(e[2] + e[2], 16), + parseInt(e[3] + e[3], 16), + Fe(parseInt(e[4] + e[4], 16), 0, 255, 0, 1) + ], + 'rgb' + ); + const n = t.match(/^(?:#|0x)?([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/); + return n + ? new wn([parseInt(n[1], 16), parseInt(n[2], 16), parseInt(n[3], 16), Fe(parseInt(n[4], 16), 0, 255, 0, 1)], 'rgb') + : null; + } + }; + function Mn(t) { + return Object.keys(Sn).reduce((e, n) => e || ((0, Sn[n])(t) ? n : null), null); + } + const Ln = (t) => { + const e = Mn(t); + return e ? Sn[e](t) : null; + }; + function An(t) { + return 'func.hsla' === t || 'func.rgba' === t || 'hex.rgba' === t; + } + function In(t) { + if ('string' == typeof t) { + const e = Ln(t); + if (e) return e; + } + return wn.black(); + } + function Tn(t) { + const e = Oe(Math.floor(t), 0, 255).toString(16); + return 1 === e.length ? `0${e}` : e; + } + function Dn(t, e = '#') { + return `${e}${mn(t.getComponents('rgb')).map(Tn).join('')}`; + } + function jn(t, e = '#') { + const n = t.getComponents('rgb'); + return `${e}${[n[0], n[1], n[2], 255 * n[3]].map(Tn).join('')}`; + } + function Bn(t) { + const e = Ce(0); + return `rgb(${mn(t.getComponents('rgb')) + .map((t) => e(t)) + .join(', ')})`; + } + function Rn(t) { + const e = Ce(2), + n = Ce(0); + return `rgba(${t + .getComponents('rgb') + .map((t, i) => (3 === i ? e : n)(t)) + .join(', ')})`; + } + const Fn = { + 'func.hsl': function (t) { + const e = [Ce(0), Ee, Ee]; + return `hsl(${mn(t.getComponents('hsl')) + .map((t, n) => e[n](t)) + .join(', ')})`; + }, + 'func.hsla': function (t) { + const e = [Ce(0), Ee, Ee, Ce(2)]; + return `hsla(${t + .getComponents('hsl') + .map((t, n) => e[n](t)) + .join(', ')})`; + }, + 'func.rgb': Bn, + 'func.rgba': Rn, + 'hex.rgb': Dn, + 'hex.rgba': jn + }; + function Un(t) { + return Fn[t]; + } + const On = v('apl'); + class Kn { + constructor(t, e) { + (this.onValueChange_ = this.onValueChange_.bind(this)), + (this.value = e.value), + this.value.emitter.on('change', this.onValueChange_), + (this.element = t.createElement('div')), + this.element.classList.add(On()), + e.viewProps.bindTabIndex(this.element); + const n = t.createElement('div'); + n.classList.add(On('b')), this.element.appendChild(n); + const i = t.createElement('div'); + i.classList.add(On('c')), n.appendChild(i), (this.colorElem_ = i); + const s = t.createElement('div'); + s.classList.add(On('m')), this.element.appendChild(s), (this.markerElem_ = s); + const o = t.createElement('div'); + o.classList.add(On('p')), this.markerElem_.appendChild(o), (this.previewElem_ = o), this.update_(); + } + update_() { + const t = this.value.rawValue, + e = t.getComponents('rgb'), + n = new wn([e[0], e[1], e[2], 0], 'rgb'), + i = new wn([e[0], e[1], e[2], 255], 'rgb'), + s = ['to right', Rn(n), Rn(i)]; + (this.colorElem_.style.background = `linear-gradient(${s.join(',')})`), (this.previewElem_.style.backgroundColor = Rn(t)); + const o = Fe(e[3], 0, 1, 0, 100); + this.markerElem_.style.left = `${o}%`; + } + onValueChange_() { + this.update_(); + } + } + class Nn { + constructor(t, e) { + (this.onKeyDown_ = this.onKeyDown_.bind(this)), + (this.onKeyUp_ = this.onKeyUp_.bind(this)), + (this.onPointerDown_ = this.onPointerDown_.bind(this)), + (this.onPointerMove_ = this.onPointerMove_.bind(this)), + (this.onPointerUp_ = this.onPointerUp_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new Kn(t, { value: this.value, viewProps: this.viewProps })), + (this.ptHandler_ = new Re(this.view.element)), + this.ptHandler_.emitter.on('down', this.onPointerDown_), + this.ptHandler_.emitter.on('move', this.onPointerMove_), + this.ptHandler_.emitter.on('up', this.onPointerUp_), + this.view.element.addEventListener('keydown', this.onKeyDown_), + this.view.element.addEventListener('keyup', this.onKeyUp_); + } + handlePointerEvent_(t, e) { + if (!t.point) return; + const n = t.point.x / t.bounds.width, + i = this.value.rawValue, + [s, o, r] = i.getComponents('hsv'); + this.value.setRawValue(new wn([s, o, r, n], 'hsv'), e); + } + onPointerDown_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerMove_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerUp_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !0, last: !0 }); + } + onKeyDown_(t) { + const e = Ie(Pn(!0), De(t)); + if (0 === e) return; + const n = this.value.rawValue, + [i, s, o, r] = n.getComponents('hsv'); + this.value.setRawValue(new wn([i, s, o, r + e], 'hsv'), { forceEmit: !1, last: !1 }); + } + onKeyUp_(t) { + 0 !== Ie(Pn(!0), De(t)) && this.value.setRawValue(this.value.rawValue, { forceEmit: !0, last: !0 }); + } + } + const $n = v('coltxt'); + class zn { + constructor(t, e) { + (this.element = t.createElement('div')), this.element.classList.add($n()); + const n = t.createElement('div'); + n.classList.add($n('m')), + (this.modeElem_ = (function (t) { + const e = t.createElement('select'); + return ( + e.appendChild( + [ + { text: 'RGB', value: 'rgb' }, + { text: 'HSL', value: 'hsl' }, + { text: 'HSV', value: 'hsv' } + ].reduce((e, n) => { + const i = t.createElement('option'); + return (i.textContent = n.text), (i.value = n.value), e.appendChild(i), e; + }, t.createDocumentFragment()) + ), + e + ); + })(t)), + this.modeElem_.classList.add($n('ms')), + n.appendChild(this.modeSelectElement); + const i = t.createElement('div'); + i.classList.add($n('mm')), i.appendChild(U(t, 'dropdown')), n.appendChild(i), this.element.appendChild(n); + const s = t.createElement('div'); + s.classList.add($n('w')), + this.element.appendChild(s), + (this.textsElem_ = s), + (this.textViews_ = e.textViews), + this.applyTextViews_(), + b(e.colorMode, (t) => { + this.modeElem_.value = t; + }); + } + get modeSelectElement() { + return this.modeElem_; + } + get textViews() { + return this.textViews_; + } + set textViews(t) { + (this.textViews_ = t), this.applyTextViews_(); + } + applyTextViews_() { + N(this.textsElem_); + const t = this.element.ownerDocument; + this.textViews_.forEach((e) => { + const n = t.createElement('div'); + n.classList.add($n('c')), n.appendChild(e.element), this.textsElem_.appendChild(n); + }); + } + } + const Hn = Ce(0), + qn = { + rgb: () => new zt({ min: 0, max: 255 }), + hsl: (t) => new zt(0 === t ? { min: 0, max: 360 } : { min: 0, max: 100 }), + hsv: (t) => new zt(0 === t ? { min: 0, max: 360 } : { min: 0, max: 100 }) + }; + function Gn(t, e, n) { + return new ze(t, { + arrayPosition: 0 === n ? 'fst' : 2 === n ? 'lst' : 'mid', + baseStep: Pn(!1), + parser: e.parser, + props: k.fromObject({ draggingScale: 1, formatter: Hn }), + value: E(0, { constraint: qn[e.colorMode](n) }), + viewProps: e.viewProps + }); + } + class Yn { + constructor(t, e) { + (this.onModeSelectChange_ = this.onModeSelectChange_.bind(this)), + (this.parser_ = e.parser), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.colorMode = E(this.value.rawValue.mode)), + (this.ccs_ = this.createComponentControllers_(t)), + (this.view = new zn(t, { + colorMode: this.colorMode, + textViews: [this.ccs_[0].view, this.ccs_[1].view, this.ccs_[2].view] + })), + this.view.modeSelectElement.addEventListener('change', this.onModeSelectChange_); + } + createComponentControllers_(t) { + const e = { colorMode: this.colorMode.rawValue, parser: this.parser_, viewProps: this.viewProps }, + n = [Gn(t, e, 0), Gn(t, e, 1), Gn(t, e, 2)]; + return ( + n.forEach((t, e) => { + Ae({ + primary: this.value, + secondary: t.value, + forward: (t) => t.rawValue.getComponents(this.colorMode.rawValue)[e], + backward: (t, n) => { + const i = this.colorMode.rawValue, + s = t.rawValue.getComponents(i); + return (s[e] = n.rawValue), new wn(bn(mn(s), s[3]), i); + } + }); + }), + n + ); + } + onModeSelectChange_(t) { + const e = t.currentTarget; + (this.colorMode.rawValue = e.value), + (this.ccs_ = this.createComponentControllers_(this.view.element.ownerDocument)), + (this.view.textViews = [this.ccs_[0].view, this.ccs_[1].view, this.ccs_[2].view]); + } + } + const Wn = v('hpl'); + class Xn { + constructor(t, e) { + (this.onValueChange_ = this.onValueChange_.bind(this)), + (this.value = e.value), + this.value.emitter.on('change', this.onValueChange_), + (this.element = t.createElement('div')), + this.element.classList.add(Wn()), + e.viewProps.bindTabIndex(this.element); + const n = t.createElement('div'); + n.classList.add(Wn('c')), this.element.appendChild(n); + const i = t.createElement('div'); + i.classList.add(Wn('m')), this.element.appendChild(i), (this.markerElem_ = i), this.update_(); + } + update_() { + const t = this.value.rawValue, + [e] = t.getComponents('hsv'); + this.markerElem_.style.backgroundColor = Bn(new wn([e, 100, 100], 'hsv')); + const n = Fe(e, 0, 360, 0, 100); + this.markerElem_.style.left = `${n}%`; + } + onValueChange_() { + this.update_(); + } + } + class Qn { + constructor(t, e) { + (this.onKeyDown_ = this.onKeyDown_.bind(this)), + (this.onKeyUp_ = this.onKeyUp_.bind(this)), + (this.onPointerDown_ = this.onPointerDown_.bind(this)), + (this.onPointerMove_ = this.onPointerMove_.bind(this)), + (this.onPointerUp_ = this.onPointerUp_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new Xn(t, { value: this.value, viewProps: this.viewProps })), + (this.ptHandler_ = new Re(this.view.element)), + this.ptHandler_.emitter.on('down', this.onPointerDown_), + this.ptHandler_.emitter.on('move', this.onPointerMove_), + this.ptHandler_.emitter.on('up', this.onPointerUp_), + this.view.element.addEventListener('keydown', this.onKeyDown_), + this.view.element.addEventListener('keyup', this.onKeyUp_); + } + handlePointerEvent_(t, e) { + if (!t.point) return; + const n = Fe(t.point.x, 0, t.bounds.width, 0, 360), + i = this.value.rawValue, + [, s, o, r] = i.getComponents('hsv'); + this.value.setRawValue(new wn([n, s, o, r], 'hsv'), e); + } + onPointerDown_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerMove_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerUp_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !0, last: !0 }); + } + onKeyDown_(t) { + const e = Ie(Pn(!1), De(t)); + if (0 === e) return; + const n = this.value.rawValue, + [i, s, o, r] = n.getComponents('hsv'); + this.value.setRawValue(new wn([i + e, s, o, r], 'hsv'), { forceEmit: !1, last: !1 }); + } + onKeyUp_(t) { + 0 !== Ie(Pn(!1), De(t)) && this.value.setRawValue(this.value.rawValue, { forceEmit: !0, last: !0 }); + } + } + const Jn = v('svp'); + class Zn { + constructor(t, e) { + (this.onValueChange_ = this.onValueChange_.bind(this)), + (this.value = e.value), + this.value.emitter.on('change', this.onValueChange_), + (this.element = t.createElement('div')), + this.element.classList.add(Jn()), + e.viewProps.bindTabIndex(this.element); + const n = t.createElement('canvas'); + (n.height = 64), (n.width = 64), n.classList.add(Jn('c')), this.element.appendChild(n), (this.canvasElement = n); + const i = t.createElement('div'); + i.classList.add(Jn('m')), this.element.appendChild(i), (this.markerElem_ = i), this.update_(); + } + update_() { + const t = (function (t) { + const e = t.ownerDocument.defaultView; + return e && 'document' in e ? t.getContext('2d') : null; + })(this.canvasElement); + if (!t) return; + const e = this.value.rawValue.getComponents('hsv'), + n = this.canvasElement.width, + i = this.canvasElement.height, + s = t.getImageData(0, 0, n, i), + o = s.data; + for (let t = 0; t < i; t++) + for (let s = 0; s < n; s++) { + const r = Fe(s, 0, n, 0, 100), + a = Fe(t, 0, i, 100, 0), + l = vn(e[0], r, a), + p = 4 * (t * n + s); + (o[p] = l[0]), (o[p + 1] = l[1]), (o[p + 2] = l[2]), (o[p + 3] = 255); + } + t.putImageData(s, 0, 0); + const r = Fe(e[1], 0, 100, 0, 100); + this.markerElem_.style.left = `${r}%`; + const a = Fe(e[2], 0, 100, 100, 0); + this.markerElem_.style.top = `${a}%`; + } + onValueChange_() { + this.update_(); + } + } + class ti { + constructor(t, e) { + (this.onKeyDown_ = this.onKeyDown_.bind(this)), + (this.onKeyUp_ = this.onKeyUp_.bind(this)), + (this.onPointerDown_ = this.onPointerDown_.bind(this)), + (this.onPointerMove_ = this.onPointerMove_.bind(this)), + (this.onPointerUp_ = this.onPointerUp_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new Zn(t, { value: this.value, viewProps: this.viewProps })), + (this.ptHandler_ = new Re(this.view.element)), + this.ptHandler_.emitter.on('down', this.onPointerDown_), + this.ptHandler_.emitter.on('move', this.onPointerMove_), + this.ptHandler_.emitter.on('up', this.onPointerUp_), + this.view.element.addEventListener('keydown', this.onKeyDown_), + this.view.element.addEventListener('keyup', this.onKeyUp_); + } + handlePointerEvent_(t, e) { + if (!t.point) return; + const n = Fe(t.point.x, 0, t.bounds.width, 0, 100), + i = Fe(t.point.y, 0, t.bounds.height, 100, 0), + [s, , , o] = this.value.rawValue.getComponents('hsv'); + this.value.setRawValue(new wn([s, n, i, o], 'hsv'), e); + } + onPointerDown_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerMove_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerUp_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !0, last: !0 }); + } + onKeyDown_(t) { + je(t.key) && t.preventDefault(); + const [e, n, i, s] = this.value.rawValue.getComponents('hsv'), + o = Pn(!1), + r = Ie(o, De(t)), + a = Ie(o, Te(t)); + (0 === r && 0 === a) || this.value.setRawValue(new wn([e, n + r, i + a, s], 'hsv'), { forceEmit: !1, last: !1 }); + } + onKeyUp_(t) { + const e = Pn(!1), + n = Ie(e, De(t)), + i = Ie(e, Te(t)); + (0 === n && 0 === i) || this.value.setRawValue(this.value.rawValue, { forceEmit: !0, last: !0 }); + } + } + class ei { + constructor(t, e) { + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.hPaletteC_ = new Qn(t, { value: this.value, viewProps: this.viewProps })), + (this.svPaletteC_ = new ti(t, { value: this.value, viewProps: this.viewProps })), + (this.alphaIcs_ = e.supportsAlpha + ? { + palette: new Nn(t, { value: this.value, viewProps: this.viewProps }), + text: new ze(t, { + parser: we, + baseStep: 0.1, + props: k.fromObject({ draggingScale: 0.01, formatter: Ce(2) }), + value: E(0, { constraint: new zt({ min: 0, max: 1 }) }), + viewProps: this.viewProps + }) + } + : null), + this.alphaIcs_ && + Ae({ + primary: this.value, + secondary: this.alphaIcs_.text.value, + forward: (t) => t.rawValue.getComponents()[3], + backward: (t, e) => { + const n = t.rawValue.getComponents(); + return (n[3] = e.rawValue), new wn(n, t.rawValue.mode); + } + }), + (this.textC_ = new Yn(t, { parser: we, value: this.value, viewProps: this.viewProps })), + (this.view = new yn(t, { + alphaViews: this.alphaIcs_ ? { palette: this.alphaIcs_.palette.view, text: this.alphaIcs_.text.view } : null, + hPaletteView: this.hPaletteC_.view, + supportsAlpha: e.supportsAlpha, + svPaletteView: this.svPaletteC_.view, + textView: this.textC_.view + })); + } + get textController() { + return this.textC_; + } + } + const ni = v('colsw'); + class ii { + constructor(t, e) { + (this.onValueChange_ = this.onValueChange_.bind(this)), + e.value.emitter.on('change', this.onValueChange_), + (this.value = e.value), + (this.element = t.createElement('div')), + this.element.classList.add(ni()), + e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('div'); + n.classList.add(ni('sw')), this.element.appendChild(n), (this.swatchElem_ = n); + const i = t.createElement('button'); + i.classList.add(ni('b')), + e.viewProps.bindDisabled(i), + this.element.appendChild(i), + (this.buttonElement = i), + this.update_(); + } + update_() { + const t = this.value.rawValue; + this.swatchElem_.style.backgroundColor = jn(t); + } + onValueChange_() { + this.update_(); + } + } + class si { + constructor(t, e) { + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new ii(t, { value: this.value, viewProps: this.viewProps })); + } + } + class oi { + constructor(t, e) { + (this.onButtonBlur_ = this.onButtonBlur_.bind(this)), + (this.onButtonClick_ = this.onButtonClick_.bind(this)), + (this.onPopupChildBlur_ = this.onPopupChildBlur_.bind(this)), + (this.onPopupChildKeydown_ = this.onPopupChildKeydown_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.foldable_ = X.create(e.expanded)), + (this.swatchC_ = new si(t, { value: this.value, viewProps: this.viewProps })); + const n = this.swatchC_.view.buttonElement; + n.addEventListener('blur', this.onButtonBlur_), + n.addEventListener('click', this.onButtonClick_), + (this.textC_ = new te(t, { + parser: e.parser, + props: k.fromObject({ formatter: e.formatter }), + value: this.value, + viewProps: this.viewProps + })), + (this.view = new un(t, { foldable: this.foldable_, pickerLayout: e.pickerLayout })), + this.view.swatchElement.appendChild(this.swatchC_.view.element), + this.view.textElement.appendChild(this.textC_.view.element), + (this.popC_ = 'popup' === e.pickerLayout ? new Qt(t, { viewProps: this.viewProps }) : null); + const i = new ei(t, { supportsAlpha: e.supportsAlpha, value: this.value, viewProps: this.viewProps }); + i.view.allFocusableElements.forEach((t) => { + t.addEventListener('blur', this.onPopupChildBlur_), t.addEventListener('keydown', this.onPopupChildKeydown_); + }), + (this.pickerC_ = i), + this.popC_ + ? (this.view.element.appendChild(this.popC_.view.element), + this.popC_.view.element.appendChild(i.view.element), + Ae({ + primary: this.foldable_.value('expanded'), + secondary: this.popC_.shows, + forward: (t) => t.rawValue, + backward: (t, e) => e.rawValue + })) + : this.view.pickerElement && + (this.view.pickerElement.appendChild(this.pickerC_.view.element), J(this.foldable_, this.view.pickerElement)); + } + get textController() { + return this.textC_; + } + onButtonBlur_(t) { + if (!this.popC_) return; + const e = this.view.element, + n = t.relatedTarget; + (n && e.contains(n)) || (this.popC_.shows.rawValue = !1); + } + onButtonClick_() { + this.foldable_.set('expanded', !this.foldable_.get('expanded')), + this.foldable_.get('expanded') && this.pickerC_.view.allFocusableElements[0].focus(); + } + onPopupChildBlur_(t) { + if (!this.popC_) return; + const e = this.popC_.view.element, + n = $(t); + (n && e.contains(n)) || + (n && n === this.swatchC_.view.buttonElement && !B(e.ownerDocument)) || + (this.popC_.shows.rawValue = !1); + } + onPopupChildKeydown_(t) { + this.popC_ + ? 'Escape' === t.key && (this.popC_.shows.rawValue = !1) + : this.view.pickerElement && 'Escape' === t.key && this.swatchC_.view.buttonElement.focus(); + } + } + function ri(t) { + return wn.isColorObject(t) ? wn.fromObject(t) : wn.black(); + } + function ai(t) { + return mn(t.getComponents('rgb')).reduce((t, e) => (t << 8) | (255 & Math.floor(e)), 0); + } + function li(t) { + return t.getComponents('rgb').reduce((t, e, n) => (t << 8) | (255 & Math.floor(3 === n ? 255 * e : e)), 0) >>> 0; + } + function pi(t) { + return 'number' != typeof t ? wn.black() : new wn([((e = t) >> 16) & 255, (e >> 8) & 255, 255 & e], 'rgb'); + var e; + } + function di(t) { + return 'number' != typeof t + ? wn.black() + : new wn([((e = t) >> 24) & 255, (e >> 16) & 255, (e >> 8) & 255, Fe(255 & e, 0, 255, 0, 1)], 'rgb'); + var e; + } + function ci(t, e) { + const n = e.toRgbaObject(); + t.writeProperty('r', n.r), t.writeProperty('g', n.g), t.writeProperty('b', n.b), t.writeProperty('a', n.a); + } + function hi(t, e) { + const n = e.toRgbaObject(); + t.writeProperty('r', n.r), t.writeProperty('g', n.g), t.writeProperty('b', n.b); + } + function ui(t) { + return 'alpha' in t && !0 === t.alpha; + } + function vi(t) { + return t ? (t) => jn(t, '0x') : (t) => Dn(t, '0x'); + } + const mi = { + id: 'input-color-number', + type: 'input', + accept: (t, e) => { + if ('number' != typeof t) return null; + if (!('view' in e)) return null; + if ('color' !== e.view) return null; + const n = Cn(e); + return n ? { initialValue: t, params: n } : null; + }, + binding: { + reader: (t) => (ui(t.params) ? di : pi), + equals: wn.equals, + writer: (t) => + (function (t) { + const e = t ? li : ai; + return (t, n) => { + Qe(t, e(n)); + }; + })(ui(t.params)) + }, + controller: (t) => { + const e = ui(t.params), + n = 'expanded' in t.params ? t.params.expanded : void 0, + i = 'picker' in t.params ? t.params.picker : void 0; + return new oi(t.document, { + expanded: null != n && n, + formatter: vi(e), + parser: Ln, + pickerLayout: null != i ? i : 'popup', + supportsAlpha: e, + value: t.value, + viewProps: t.viewProps + }); + } + }; + const bi = { + id: 'input-color-object', + type: 'input', + accept: (t, e) => { + if (!wn.isColorObject(t)) return null; + const n = Cn(e); + return n ? { initialValue: t, params: n } : null; + }, + binding: { + reader: (t) => ri, + equals: wn.equals, + writer: (t) => { + return (e = t.initialValue), wn.isRgbaColorObject(e) ? ci : hi; + var e; + } + }, + controller: (t) => { + const e = wn.isRgbaColorObject(t.initialValue), + n = 'expanded' in t.params ? t.params.expanded : void 0, + i = 'picker' in t.params ? t.params.picker : void 0, + s = e ? jn : Dn; + return new oi(t.document, { + expanded: null != n && n, + formatter: s, + parser: Ln, + pickerLayout: null != i ? i : 'popup', + supportsAlpha: e, + value: t.value, + viewProps: t.viewProps + }); + } + }, + gi = { + id: 'input-color-string', + type: 'input', + accept: (t, e) => { + if ('string' != typeof t) return null; + if ('view' in e && 'text' === e.view) return null; + if (!Mn(t)) return null; + const n = Cn(e); + return n ? { initialValue: t, params: n } : null; + }, + binding: { + reader: (t) => In, + equals: wn.equals, + writer: (t) => { + const e = Mn(t.initialValue); + if (!e) throw p.shouldNeverHappen(); + return (function (t) { + const e = Un(t); + return (t, n) => { + Qe(t, e(n)); + }; + })(e); + } + }, + controller: (t) => { + const e = Mn(t.initialValue); + if (!e) throw p.shouldNeverHappen(); + const n = Un(e), + i = 'expanded' in t.params ? t.params.expanded : void 0, + s = 'picker' in t.params ? t.params.picker : void 0; + return new oi(t.document, { + expanded: null != i && i, + formatter: n, + parser: Ln, + pickerLayout: null != s ? s : 'popup', + supportsAlpha: An(e), + value: t.value, + viewProps: t.viewProps + }); + } + }; + class _i { + constructor(t) { + (this.components = t.components), (this.asm_ = t.assembly); + } + constrain(t) { + const e = this.asm_.toComponents(t).map((t, e) => { + var n, i; + return null !== (i = null === (n = this.components[e]) || void 0 === n ? void 0 : n.constrain(t)) && void 0 !== i ? i : t; + }); + return this.asm_.fromComponents(e); + } + } + const fi = v('pndtxt'); + class wi { + constructor(t, e) { + (this.textViews = e.textViews), + (this.element = t.createElement('div')), + this.element.classList.add(fi()), + this.textViews.forEach((e) => { + const n = t.createElement('div'); + n.classList.add(fi('a')), n.appendChild(e.element), this.element.appendChild(n); + }); + } + } + class xi { + constructor(t, e) { + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.acs_ = e.axes.map((n, i) => + (function (t, e, n) { + return new ze(t, { + arrayPosition: 0 === n ? 'fst' : n === e.axes.length - 1 ? 'lst' : 'mid', + baseStep: e.axes[n].baseStep, + parser: e.parser, + props: e.axes[n].textProps, + value: E(0, { constraint: e.axes[n].constraint }), + viewProps: e.viewProps + }); + })(t, e, i) + )), + this.acs_.forEach((t, n) => { + Ae({ + primary: this.value, + secondary: t.value, + forward: (t) => e.assembly.toComponents(t.rawValue)[n], + backward: (t, i) => { + const s = e.assembly.toComponents(t.rawValue); + return (s[n] = i.rawValue), e.assembly.fromComponents(s); + } + }); + }), + (this.view = new wi(t, { textViews: this.acs_.map((t) => t.view) })); + } + } + function yi(t) { + const e = [], + n = (function (t) { + return 'step' in t && !r(t.step) ? new Ht(t.step) : null; + })(t); + n && e.push(n); + const i = (function (t) { + return ('max' in t && !r(t.max)) || ('min' in t && !r(t.min)) ? new zt({ max: t.max, min: t.min }) : null; + })(t); + i && e.push(i); + const s = nn(t.options); + return s && e.push(s), new Kt(e); + } + function Ci(t) { + const [e, n] = (function (t) { + const e = t ? Nt(t, zt) : null; + return e ? [e.minValue, e.maxValue] : [void 0, void 0]; + })(t); + return [null != e ? e : 0, null != n ? n : 100]; + } + const Pi = { + id: 'input-number', + type: 'input', + accept: (t, e) => { + if ('number' != typeof t) return null; + const n = M, + i = L(e, { + format: n.optional.function, + max: n.optional.number, + min: n.optional.number, + options: n.optional.custom(Je), + step: n.optional.number + }); + return i ? { initialValue: t, params: i } : null; + }, + binding: { reader: (t) => xe, constraint: (t) => yi(t.params), writer: (t) => Qe }, + controller: (t) => { + var e, n; + const i = t.value, + s = t.constraint; + if (s && Nt(s, $t)) + return new Yt(t.document, { + props: k.fromObject({ options: null !== (e = sn(s)) && void 0 !== e ? e : [] }), + value: i, + viewProps: t.viewProps + }); + const o = null !== (n = 'format' in t.params ? t.params.format : void 0) && void 0 !== n ? n : Ce(on(s, i.rawValue)); + if (s && Nt(s, zt)) { + const [e, n] = Ci(s); + return new Xe(t.document, { + baseStep: rn(s), + parser: we, + sliderProps: k.fromObject({ maxValue: n, minValue: e }), + textProps: k.fromObject({ draggingScale: an(s, i.rawValue), formatter: o }), + value: i, + viewProps: t.viewProps + }); + } + return new ze(t.document, { + baseStep: rn(s), + parser: we, + props: k.fromObject({ draggingScale: an(s, i.rawValue), formatter: o }), + value: i, + viewProps: t.viewProps + }); + } + }; + class Ei { + constructor(t = 0, e = 0) { + (this.x = t), (this.y = e); + } + getComponents() { + return [this.x, this.y]; + } + static isObject(t) { + if (r(t)) return !1; + const e = t.x, + n = t.y; + return 'number' == typeof e && 'number' == typeof n; + } + static equals(t, e) { + return t.x === e.x && t.y === e.y; + } + toObject() { + return { x: this.x, y: this.y }; + } + } + const ki = { toComponents: (t) => t.getComponents(), fromComponents: (t) => new Ei(...t) }, + Vi = v('p2d'); + class Si { + constructor(t, e) { + (this.element = t.createElement('div')), + this.element.classList.add(Vi()), + e.viewProps.bindClassModifiers(this.element), + b(e.expanded, _(this.element, Vi(void 0, 'expanded'))); + const n = t.createElement('div'); + n.classList.add(Vi('h')), this.element.appendChild(n); + const i = t.createElement('button'); + i.classList.add(Vi('b')), + i.appendChild(U(t, 'p2dpad')), + e.viewProps.bindDisabled(i), + n.appendChild(i), + (this.buttonElement = i); + const s = t.createElement('div'); + if ((s.classList.add(Vi('t')), n.appendChild(s), (this.textElement = s), 'inline' === e.pickerLayout)) { + const e = t.createElement('div'); + e.classList.add(Vi('p')), this.element.appendChild(e), (this.pickerElement = e); + } else this.pickerElement = null; + } + } + const Mi = v('p2dp'); + class Li { + constructor(t, e) { + (this.onFoldableChange_ = this.onFoldableChange_.bind(this)), + (this.onValueChange_ = this.onValueChange_.bind(this)), + (this.invertsY_ = e.invertsY), + (this.maxValue_ = e.maxValue), + (this.element = t.createElement('div')), + this.element.classList.add(Mi()), + 'popup' === e.layout && this.element.classList.add(Mi(void 0, 'p')); + const n = t.createElement('div'); + n.classList.add(Mi('p')), e.viewProps.bindTabIndex(n), this.element.appendChild(n), (this.padElement = n); + const i = t.createElementNS(D, 'svg'); + i.classList.add(Mi('g')), this.padElement.appendChild(i), (this.svgElem_ = i); + const s = t.createElementNS(D, 'line'); + s.classList.add(Mi('ax')), + s.setAttributeNS(null, 'x1', '0'), + s.setAttributeNS(null, 'y1', '50%'), + s.setAttributeNS(null, 'x2', '100%'), + s.setAttributeNS(null, 'y2', '50%'), + this.svgElem_.appendChild(s); + const o = t.createElementNS(D, 'line'); + o.classList.add(Mi('ax')), + o.setAttributeNS(null, 'x1', '50%'), + o.setAttributeNS(null, 'y1', '0'), + o.setAttributeNS(null, 'x2', '50%'), + o.setAttributeNS(null, 'y2', '100%'), + this.svgElem_.appendChild(o); + const r = t.createElementNS(D, 'line'); + r.classList.add(Mi('l')), + r.setAttributeNS(null, 'x1', '50%'), + r.setAttributeNS(null, 'y1', '50%'), + this.svgElem_.appendChild(r), + (this.lineElem_ = r); + const a = t.createElement('div'); + a.classList.add(Mi('m')), + this.padElement.appendChild(a), + (this.markerElem_ = a), + e.value.emitter.on('change', this.onValueChange_), + (this.value = e.value), + this.update_(); + } + get allFocusableElements() { + return [this.padElement]; + } + update_() { + const [t, e] = this.value.rawValue.getComponents(), + n = this.maxValue_, + i = Fe(t, -n, +n, 0, 100), + s = Fe(e, -n, +n, 0, 100), + o = this.invertsY_ ? 100 - s : s; + this.lineElem_.setAttributeNS(null, 'x2', `${i}%`), + this.lineElem_.setAttributeNS(null, 'y2', `${o}%`), + (this.markerElem_.style.left = `${i}%`), + (this.markerElem_.style.top = `${o}%`); + } + onValueChange_() { + this.update_(); + } + onFoldableChange_() { + this.update_(); + } + } + function Ai(t, e, n) { + return [Ie(e[0], De(t)), Ie(e[1], Te(t)) * (n ? 1 : -1)]; + } + class Ii { + constructor(t, e) { + (this.onPadKeyDown_ = this.onPadKeyDown_.bind(this)), + (this.onPadKeyUp_ = this.onPadKeyUp_.bind(this)), + (this.onPointerDown_ = this.onPointerDown_.bind(this)), + (this.onPointerMove_ = this.onPointerMove_.bind(this)), + (this.onPointerUp_ = this.onPointerUp_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.baseSteps_ = e.baseSteps), + (this.maxValue_ = e.maxValue), + (this.invertsY_ = e.invertsY), + (this.view = new Li(t, { + invertsY: this.invertsY_, + layout: e.layout, + maxValue: this.maxValue_, + value: this.value, + viewProps: this.viewProps + })), + (this.ptHandler_ = new Re(this.view.padElement)), + this.ptHandler_.emitter.on('down', this.onPointerDown_), + this.ptHandler_.emitter.on('move', this.onPointerMove_), + this.ptHandler_.emitter.on('up', this.onPointerUp_), + this.view.padElement.addEventListener('keydown', this.onPadKeyDown_), + this.view.padElement.addEventListener('keyup', this.onPadKeyUp_); + } + handlePointerEvent_(t, e) { + if (!t.point) return; + const n = this.maxValue_, + i = Fe(t.point.x, 0, t.bounds.width, -n, +n), + s = Fe(this.invertsY_ ? t.bounds.height - t.point.y : t.point.y, 0, t.bounds.height, -n, +n); + this.value.setRawValue(new Ei(i, s), e); + } + onPointerDown_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerMove_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !1, last: !1 }); + } + onPointerUp_(t) { + this.handlePointerEvent_(t.data, { forceEmit: !0, last: !0 }); + } + onPadKeyDown_(t) { + je(t.key) && t.preventDefault(); + const [e, n] = Ai(t, this.baseSteps_, this.invertsY_); + (0 === e && 0 === n) || + this.value.setRawValue(new Ei(this.value.rawValue.x + e, this.value.rawValue.y + n), { forceEmit: !1, last: !1 }); + } + onPadKeyUp_(t) { + const [e, n] = Ai(t, this.baseSteps_, this.invertsY_); + (0 === e && 0 === n) || this.value.setRawValue(this.value.rawValue, { forceEmit: !0, last: !0 }); + } + } + class Ti { + constructor(t, e) { + var n, i; + (this.onPopupChildBlur_ = this.onPopupChildBlur_.bind(this)), + (this.onPopupChildKeydown_ = this.onPopupChildKeydown_.bind(this)), + (this.onPadButtonBlur_ = this.onPadButtonBlur_.bind(this)), + (this.onPadButtonClick_ = this.onPadButtonClick_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.foldable_ = X.create(e.expanded)), + (this.popC_ = 'popup' === e.pickerLayout ? new Qt(t, { viewProps: this.viewProps }) : null); + const s = new Ii(t, { + baseSteps: [e.axes[0].baseStep, e.axes[1].baseStep], + invertsY: e.invertsY, + layout: e.pickerLayout, + maxValue: e.maxValue, + value: this.value, + viewProps: this.viewProps + }); + s.view.allFocusableElements.forEach((t) => { + t.addEventListener('blur', this.onPopupChildBlur_), t.addEventListener('keydown', this.onPopupChildKeydown_); + }), + (this.pickerC_ = s), + (this.textC_ = new xi(t, { assembly: ki, axes: e.axes, parser: e.parser, value: this.value, viewProps: this.viewProps })), + (this.view = new Si(t, { + expanded: this.foldable_.value('expanded'), + pickerLayout: e.pickerLayout, + viewProps: this.viewProps + })), + this.view.textElement.appendChild(this.textC_.view.element), + null === (n = this.view.buttonElement) || void 0 === n || n.addEventListener('blur', this.onPadButtonBlur_), + null === (i = this.view.buttonElement) || void 0 === i || i.addEventListener('click', this.onPadButtonClick_), + this.popC_ + ? (this.view.element.appendChild(this.popC_.view.element), + this.popC_.view.element.appendChild(this.pickerC_.view.element), + Ae({ + primary: this.foldable_.value('expanded'), + secondary: this.popC_.shows, + forward: (t) => t.rawValue, + backward: (t, e) => e.rawValue + })) + : this.view.pickerElement && + (this.view.pickerElement.appendChild(this.pickerC_.view.element), J(this.foldable_, this.view.pickerElement)); + } + onPadButtonBlur_(t) { + if (!this.popC_) return; + const e = this.view.element, + n = t.relatedTarget; + (n && e.contains(n)) || (this.popC_.shows.rawValue = !1); + } + onPadButtonClick_() { + this.foldable_.set('expanded', !this.foldable_.get('expanded')), + this.foldable_.get('expanded') && this.pickerC_.view.allFocusableElements[0].focus(); + } + onPopupChildBlur_(t) { + if (!this.popC_) return; + const e = this.popC_.view.element, + n = $(t); + (n && e.contains(n)) || (n && n === this.view.buttonElement && !B(e.ownerDocument)) || (this.popC_.shows.rawValue = !1); + } + onPopupChildKeydown_(t) { + this.popC_ + ? 'Escape' === t.key && (this.popC_.shows.rawValue = !1) + : this.view.pickerElement && 'Escape' === t.key && this.view.buttonElement.focus(); + } + } + function Di(t) { + return Ei.isObject(t) ? new Ei(t.x, t.y) : new Ei(); + } + function ji(t, e) { + t.writeProperty('x', e.x), t.writeProperty('y', e.y); + } + function Bi(t) { + if (!t) return; + const e = []; + return r(t.step) || e.push(new Ht(t.step)), (r(t.max) && r(t.min)) || e.push(new zt({ max: t.max, min: t.min })), new Kt(e); + } + function Ri(t, e) { + const n = t && Nt(t, zt); + if (n) return Math.max(Math.abs(n.minValue || 0), Math.abs(n.maxValue || 0)); + const i = rn(t); + return Math.max(10 * Math.abs(i), 10 * Math.abs(e)); + } + function Fi(t, e) { + const n = e instanceof _i ? e.components[0] : void 0, + i = e instanceof _i ? e.components[1] : void 0, + s = Ri(n, t.x), + o = Ri(i, t.y); + return Math.max(s, o); + } + function Ui(t, e) { + return { baseStep: rn(e), constraint: e, textProps: k.fromObject({ draggingScale: an(e, t), formatter: Ce(on(e, t)) }) }; + } + function Oi(t) { + if (!('y' in t)) return !1; + const e = t.y; + return !!e && 'inverted' in e && !!e.inverted; + } + const Ki = { + id: 'input-point2d', + type: 'input', + accept: (t, e) => { + if (!Ei.isObject(t)) return null; + const n = M, + i = L(e, { + expanded: n.optional.boolean, + picker: n.optional.custom(Ze), + x: n.optional.custom(tn), + y: n.optional.object({ + inverted: n.optional.boolean, + max: n.optional.number, + min: n.optional.number, + step: n.optional.number + }) + }); + return i ? { initialValue: t, params: i } : null; + }, + binding: { + reader: (t) => Di, + constraint: (t) => { + return (e = t.params), new _i({ assembly: ki, components: [Bi('x' in e ? e.x : void 0), Bi('y' in e ? e.y : void 0)] }); + var e; + }, + equals: Ei.equals, + writer: (t) => ji + }, + controller: (t) => { + const e = t.document, + n = t.value, + i = t.constraint; + if (!(i instanceof _i)) throw p.shouldNeverHappen(); + const s = 'expanded' in t.params ? t.params.expanded : void 0, + o = 'picker' in t.params ? t.params.picker : void 0; + return new Ti(e, { + axes: [Ui(n.rawValue.x, i.components[0]), Ui(n.rawValue.y, i.components[1])], + expanded: null != s && s, + invertsY: Oi(t.params), + maxValue: Fi(n.rawValue, i), + parser: we, + pickerLayout: null != o ? o : 'popup', + value: n, + viewProps: t.viewProps + }); + } + }; + class Ni { + constructor(t = 0, e = 0, n = 0) { + (this.x = t), (this.y = e), (this.z = n); + } + getComponents() { + return [this.x, this.y, this.z]; + } + static isObject(t) { + if (r(t)) return !1; + const e = t.x, + n = t.y, + i = t.z; + return 'number' == typeof e && 'number' == typeof n && 'number' == typeof i; + } + static equals(t, e) { + return t.x === e.x && t.y === e.y && t.z === e.z; + } + toObject() { + return { x: this.x, y: this.y, z: this.z }; + } + } + const $i = { toComponents: (t) => t.getComponents(), fromComponents: (t) => new Ni(...t) }; + function zi(t) { + return Ni.isObject(t) ? new Ni(t.x, t.y, t.z) : new Ni(); + } + function Hi(t, e) { + t.writeProperty('x', e.x), t.writeProperty('y', e.y), t.writeProperty('z', e.z); + } + function qi(t) { + if (!t) return; + const e = []; + return r(t.step) || e.push(new Ht(t.step)), (r(t.max) && r(t.min)) || e.push(new zt({ max: t.max, min: t.min })), new Kt(e); + } + function Gi(t, e) { + return { baseStep: rn(e), constraint: e, textProps: k.fromObject({ draggingScale: an(e, t), formatter: Ce(on(e, t)) }) }; + } + const Yi = { + id: 'input-point3d', + type: 'input', + accept: (t, e) => { + if (!Ni.isObject(t)) return null; + const n = M, + i = L(e, { x: n.optional.custom(tn), y: n.optional.custom(tn), z: n.optional.custom(tn) }); + return i ? { initialValue: t, params: i } : null; + }, + binding: { + reader: (t) => zi, + constraint: (t) => { + return ( + (e = t.params), + new _i({ + assembly: $i, + components: [qi('x' in e ? e.x : void 0), qi('y' in e ? e.y : void 0), qi('z' in e ? e.z : void 0)] + }) + ); + var e; + }, + equals: Ni.equals, + writer: (t) => Hi + }, + controller: (t) => { + const e = t.value, + n = t.constraint; + if (!(n instanceof _i)) throw p.shouldNeverHappen(); + return new xi(t.document, { + assembly: $i, + axes: [Gi(e.rawValue.x, n.components[0]), Gi(e.rawValue.y, n.components[1]), Gi(e.rawValue.z, n.components[2])], + parser: we, + value: e, + viewProps: t.viewProps + }); + } + }; + class Wi { + constructor(t = 0, e = 0, n = 0, i = 0) { + (this.x = t), (this.y = e), (this.z = n), (this.w = i); + } + getComponents() { + return [this.x, this.y, this.z, this.w]; + } + static isObject(t) { + if (r(t)) return !1; + const e = t.x, + n = t.y, + i = t.z, + s = t.w; + return 'number' == typeof e && 'number' == typeof n && 'number' == typeof i && 'number' == typeof s; + } + static equals(t, e) { + return t.x === e.x && t.y === e.y && t.z === e.z && t.w === e.w; + } + toObject() { + return { x: this.x, y: this.y, z: this.z, w: this.w }; + } + } + const Xi = { toComponents: (t) => t.getComponents(), fromComponents: (t) => new Wi(...t) }; + function Qi(t) { + return Wi.isObject(t) ? new Wi(t.x, t.y, t.z, t.w) : new Wi(); + } + function Ji(t, e) { + t.writeProperty('x', e.x), t.writeProperty('y', e.y), t.writeProperty('z', e.z), t.writeProperty('w', e.w); + } + function Zi(t) { + if (!t) return; + const e = []; + return r(t.step) || e.push(new Ht(t.step)), (r(t.max) && r(t.min)) || e.push(new zt({ max: t.max, min: t.min })), new Kt(e); + } + const ts = { + id: 'input-point4d', + type: 'input', + accept: (t, e) => { + if (!Wi.isObject(t)) return null; + const n = M, + i = L(e, { x: n.optional.custom(tn), y: n.optional.custom(tn), z: n.optional.custom(tn), w: n.optional.custom(tn) }); + return i ? { initialValue: t, params: i } : null; + }, + binding: { + reader: (t) => Qi, + constraint: (t) => { + return ( + (e = t.params), + new _i({ + assembly: Xi, + components: [ + Zi('x' in e ? e.x : void 0), + Zi('y' in e ? e.y : void 0), + Zi('z' in e ? e.z : void 0), + Zi('w' in e ? e.w : void 0) + ] + }) + ); + var e; + }, + equals: Wi.equals, + writer: (t) => Ji + }, + controller: (t) => { + const e = t.value, + n = t.constraint; + if (!(n instanceof _i)) throw p.shouldNeverHappen(); + return new xi(t.document, { + assembly: Xi, + axes: e.rawValue.getComponents().map((t, e) => { + return ( + (i = t), + { + baseStep: rn((s = n.components[e])), + constraint: s, + textProps: k.fromObject({ draggingScale: an(s, i), formatter: Ce(on(s, i)) }) + } + ); + var i, s; + }), + parser: we, + value: e, + viewProps: t.viewProps + }); + } + }; + const es = { + id: 'input-string', + type: 'input', + accept: (t, e) => { + if ('string' != typeof t) return null; + const n = L(e, { options: M.optional.custom(Je) }); + return n ? { initialValue: t, params: n } : null; + }, + binding: { + reader: (t) => ke, + constraint: (t) => + (function (t) { + const e = [], + n = nn(t.options); + return n && e.push(n), new Kt(e); + })(t.params), + writer: (t) => Qe + }, + controller: (t) => { + var e; + const n = t.document, + i = t.value, + s = t.constraint; + return s && Nt(s, $t) + ? new Yt(n, { + props: k.fromObject({ options: null !== (e = sn(s)) && void 0 !== e ? e : [] }), + value: i, + viewProps: t.viewProps + }) + : new te(n, { parser: (t) => t, props: k.fromObject({ formatter: Ve }), value: i, viewProps: t.viewProps }); + } + }, + ns = { defaultInterval: 200, defaultLineCount: 3 }, + is = v('mll'); + class ss { + constructor(t, e) { + (this.onValueUpdate_ = this.onValueUpdate_.bind(this)), + (this.formatter_ = e.formatter), + (this.element = t.createElement('div')), + this.element.classList.add(is()), + e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('textarea'); + n.classList.add(is('i')), + (n.style.height = `calc(var(--bld-us) * ${e.lineCount})`), + (n.readOnly = !0), + e.viewProps.bindDisabled(n), + this.element.appendChild(n), + (this.textareaElem_ = n), + e.value.emitter.on('change', this.onValueUpdate_), + (this.value = e.value), + this.update_(); + } + update_() { + const t = this.textareaElem_, + e = t.scrollTop === t.scrollHeight - t.clientHeight, + n = []; + this.value.rawValue.forEach((t) => { + void 0 !== t && n.push(this.formatter_(t)); + }), + (t.textContent = n.join('\n')), + e && (t.scrollTop = t.scrollHeight); + } + onValueUpdate_() { + this.update_(); + } + } + class os { + constructor(t, e) { + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new ss(t, { formatter: e.formatter, lineCount: e.lineCount, value: this.value, viewProps: this.viewProps })); + } + } + const rs = v('sgl'); + class as { + constructor(t, e) { + (this.onValueUpdate_ = this.onValueUpdate_.bind(this)), + (this.formatter_ = e.formatter), + (this.element = t.createElement('div')), + this.element.classList.add(rs()), + e.viewProps.bindClassModifiers(this.element); + const n = t.createElement('input'); + n.classList.add(rs('i')), + (n.readOnly = !0), + (n.type = 'text'), + e.viewProps.bindDisabled(n), + this.element.appendChild(n), + (this.inputElement = n), + e.value.emitter.on('change', this.onValueUpdate_), + (this.value = e.value), + this.update_(); + } + update_() { + const t = this.value.rawValue, + e = t[t.length - 1]; + this.inputElement.value = void 0 !== e ? this.formatter_(e) : ''; + } + onValueUpdate_() { + this.update_(); + } + } + class ls { + constructor(t, e) { + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.view = new as(t, { formatter: e.formatter, value: this.value, viewProps: this.viewProps })); + } + } + const ps = { + id: 'monitor-bool', + type: 'monitor', + accept: (t, e) => { + if ('boolean' != typeof t) return null; + const n = L(e, { lineCount: M.optional.number }); + return n ? { initialValue: t, params: n } : null; + }, + binding: { reader: (t) => ee }, + controller: (t) => { + var e; + return 1 === t.value.rawValue.length + ? new ls(t.document, { formatter: ne, value: t.value, viewProps: t.viewProps }) + : new os(t.document, { + formatter: ne, + lineCount: null !== (e = t.params.lineCount) && void 0 !== e ? e : ns.defaultLineCount, + value: t.value, + viewProps: t.viewProps + }); + } + }; + class ds { + constructor() { + (this.emitter = new h()), (this.index_ = -1); + } + get index() { + return this.index_; + } + set index(t) { + this.index_ !== t && ((this.index_ = t), this.emitter.emit('change', { index: t, sender: this })); + } + } + const cs = v('grl'); + class hs { + constructor(t, e) { + (this.onCursorChange_ = this.onCursorChange_.bind(this)), + (this.onValueUpdate_ = this.onValueUpdate_.bind(this)), + (this.element = t.createElement('div')), + this.element.classList.add(cs()), + e.viewProps.bindClassModifiers(this.element), + (this.formatter_ = e.formatter), + (this.minValue_ = e.minValue), + (this.maxValue_ = e.maxValue), + (this.cursor_ = e.cursor), + this.cursor_.emitter.on('change', this.onCursorChange_); + const n = t.createElementNS(D, 'svg'); + n.classList.add(cs('g')), + (n.style.height = `calc(var(--bld-us) * ${e.lineCount})`), + this.element.appendChild(n), + (this.svgElem_ = n); + const i = t.createElementNS(D, 'polyline'); + this.svgElem_.appendChild(i), (this.lineElem_ = i); + const s = t.createElement('div'); + s.classList.add(cs('t'), v('tt')()), + this.element.appendChild(s), + (this.tooltipElem_ = s), + e.value.emitter.on('change', this.onValueUpdate_), + (this.value = e.value), + this.update_(); + } + get graphElement() { + return this.svgElem_; + } + update_() { + const t = this.svgElem_.getBoundingClientRect(), + e = this.value.rawValue.length - 1, + n = this.minValue_, + i = this.maxValue_, + s = []; + this.value.rawValue.forEach((o, r) => { + if (void 0 === o) return; + const a = Fe(r, 0, e, 0, t.width), + l = Fe(o, n, i, t.height, 0); + s.push([a, l].join(',')); + }), + this.lineElem_.setAttributeNS(null, 'points', s.join(' ')); + const o = this.tooltipElem_, + r = this.value.rawValue[this.cursor_.index]; + if (void 0 === r) return void o.classList.remove(cs('t', 'a')); + const a = Fe(this.cursor_.index, 0, e, 0, t.width), + l = Fe(r, n, i, t.height, 0); + (o.style.left = `${a}px`), + (o.style.top = `${l}px`), + (o.textContent = `${this.formatter_(r)}`), + o.classList.contains(cs('t', 'a')) || + (o.classList.add(cs('t', 'a'), cs('t', 'in')), j(o), o.classList.remove(cs('t', 'in'))); + } + onValueUpdate_() { + this.update_(); + } + onCursorChange_() { + this.update_(); + } + } + class us { + constructor(t, e) { + if ( + ((this.onGraphMouseMove_ = this.onGraphMouseMove_.bind(this)), + (this.onGraphMouseLeave_ = this.onGraphMouseLeave_.bind(this)), + (this.onGraphPointerDown_ = this.onGraphPointerDown_.bind(this)), + (this.onGraphPointerMove_ = this.onGraphPointerMove_.bind(this)), + (this.onGraphPointerUp_ = this.onGraphPointerUp_.bind(this)), + (this.value = e.value), + (this.viewProps = e.viewProps), + (this.cursor_ = new ds()), + (this.view = new hs(t, { + cursor: this.cursor_, + formatter: e.formatter, + lineCount: e.lineCount, + maxValue: e.maxValue, + minValue: e.minValue, + value: this.value, + viewProps: this.viewProps + })), + B(t)) + ) { + const t = new Re(this.view.element); + t.emitter.on('down', this.onGraphPointerDown_), + t.emitter.on('move', this.onGraphPointerMove_), + t.emitter.on('up', this.onGraphPointerUp_); + } else + this.view.element.addEventListener('mousemove', this.onGraphMouseMove_), + this.view.element.addEventListener('mouseleave', this.onGraphMouseLeave_); + } + onGraphMouseLeave_() { + this.cursor_.index = -1; + } + onGraphMouseMove_(t) { + const e = this.view.element.getBoundingClientRect(); + this.cursor_.index = Math.floor(Fe(t.offsetX, 0, e.width, 0, this.value.rawValue.length)); + } + onGraphPointerDown_(t) { + this.onGraphPointerMove_(t); + } + onGraphPointerMove_(t) { + t.data.point + ? (this.cursor_.index = Math.floor(Fe(t.data.point.x, 0, t.data.bounds.width, 0, this.value.rawValue.length))) + : (this.cursor_.index = -1); + } + onGraphPointerUp_() { + this.cursor_.index = -1; + } + } + function vs(t) { + return 'format' in t && !r(t.format) ? t.format : Ce(2); + } + function ms(t) { + return 'view' in t && 'graph' === t.view; + } + const bs = { + id: 'monitor-number', + type: 'monitor', + accept: (t, e) => { + if ('number' != typeof t) return null; + const n = M, + i = L(e, { + format: n.optional.function, + lineCount: n.optional.number, + max: n.optional.number, + min: n.optional.number, + view: n.optional.string + }); + return i ? { initialValue: t, params: i } : null; + }, + binding: { defaultBufferSize: (t) => (ms(t) ? 64 : 1), reader: (t) => xe }, + controller: (t) => + ms(t.params) + ? (function (t) { + var e, n, i; + return new us(t.document, { + formatter: vs(t.params), + lineCount: null !== (e = t.params.lineCount) && void 0 !== e ? e : ns.defaultLineCount, + maxValue: null !== (n = 'max' in t.params ? t.params.max : null) && void 0 !== n ? n : 100, + minValue: null !== (i = 'min' in t.params ? t.params.min : null) && void 0 !== i ? i : 0, + value: t.value, + viewProps: t.viewProps + }); + })(t) + : (function (t) { + var e; + return 1 === t.value.rawValue.length + ? new ls(t.document, { formatter: vs(t.params), value: t.value, viewProps: t.viewProps }) + : new os(t.document, { + formatter: vs(t.params), + lineCount: null !== (e = t.params.lineCount) && void 0 !== e ? e : ns.defaultLineCount, + value: t.value, + viewProps: t.viewProps + }); + })(t) + }, + gs = { + id: 'monitor-string', + type: 'monitor', + accept: (t, e) => { + if ('string' != typeof t) return null; + const n = M, + i = L(e, { lineCount: n.optional.number, multiline: n.optional.boolean }); + return i ? { initialValue: t, params: i } : null; + }, + binding: { reader: (t) => ke }, + controller: (t) => { + var e; + const n = t.value; + return n.rawValue.length > 1 || ('multiline' in t.params && t.params.multiline) + ? new os(t.document, { + formatter: Ve, + lineCount: null !== (e = t.params.lineCount) && void 0 !== e ? e : ns.defaultLineCount, + value: n, + viewProps: t.viewProps + }) + : new ls(t.document, { formatter: Ve, value: n, viewProps: t.viewProps }); + } + }; + class _s { + constructor(t) { + (this.onValueChange_ = this.onValueChange_.bind(this)), + (this.reader = t.reader), + (this.writer = t.writer), + (this.emitter = new h()), + (this.value = t.value), + this.value.emitter.on('change', this.onValueChange_), + (this.target = t.target), + this.read(); + } + read() { + const t = this.target.read(); + void 0 !== t && (this.value.rawValue = this.reader(t)); + } + write_(t) { + this.writer(this.target, t); + } + onValueChange_(t) { + this.write_(t.rawValue), this.emitter.emit('change', { options: t.options, rawValue: t.rawValue, sender: this }); + } + } + class fs { + constructor(t) { + (this.onTick_ = this.onTick_.bind(this)), + (this.reader_ = t.reader), + (this.target = t.target), + (this.emitter = new h()), + (this.value = t.value), + (this.ticker = t.ticker), + this.ticker.emitter.on('tick', this.onTick_), + this.read(); + } + dispose() { + this.ticker.dispose(); + } + read() { + const t = this.target.read(); + if (void 0 === t) return; + const e = this.value.rawValue, + n = this.reader_(t); + (this.value.rawValue = (function (t, e) { + const n = [...Le(t), e]; + return n.length > t.length ? n.splice(0, n.length - t.length) : Se(n, t.length), n; + })(e, n)), + this.emitter.emit('update', { rawValue: n, sender: this }); + } + onTick_(t) { + this.read(); + } + } + function ws(t, e) { + return 0 === e ? new Ut() : new Ot(t, null != e ? e : ns.defaultInterval); + } + class xs { + constructor() { + this.pluginsMap_ = { blades: [], inputs: [], monitors: [] }; + } + getAll() { + return [...this.pluginsMap_.blades, ...this.pluginsMap_.inputs, ...this.pluginsMap_.monitors]; + } + register(t) { + 'blade' === t.type + ? this.pluginsMap_.blades.unshift(t) + : 'input' === t.type + ? this.pluginsMap_.inputs.unshift(t) + : 'monitor' === t.type && this.pluginsMap_.monitors.unshift(t); + } + createInput(t, e, n) { + if (r(e.read())) throw new p({ context: { key: e.key }, type: 'nomatchingcontroller' }); + const i = this.pluginsMap_.inputs.reduce( + (i, s) => + i || + (function (t, e) { + const n = t.accept(e.target.read(), e.params); + if (r(n)) return null; + const i = M, + s = { target: e.target, initialValue: n.initialValue, params: n.params }, + o = t.binding.reader(s), + a = t.binding.constraint ? t.binding.constraint(s) : void 0, + l = E(o(n.initialValue), { constraint: a, equals: t.binding.equals }), + p = new _s({ reader: o, target: e.target, value: l, writer: t.binding.writer(s) }), + d = i.optional.boolean(e.params.disabled).value, + c = i.optional.boolean(e.params.hidden).value, + h = t.controller({ + constraint: a, + document: e.document, + initialValue: n.initialValue, + params: n.params, + value: p.value, + viewProps: St.create({ disabled: d, hidden: c }) + }), + u = i.optional.string(e.params.label).value; + return new nt(e.document, { + binding: p, + blade: W(), + props: k.fromObject({ label: u || e.target.key }), + valueController: h + }); + })(s, { document: t, target: e, params: n }), + null + ); + if (i) return i; + throw new p({ context: { key: e.key }, type: 'nomatchingcontroller' }); + } + createMonitor(t, e, n) { + const i = this.pluginsMap_.monitors.reduce( + (i, s) => + i || + (function (t, e) { + var n, i, s; + const o = M, + a = t.accept(e.target.read(), e.params); + if (r(a)) return null; + const l = { target: e.target, initialValue: a.initialValue, params: a.params }, + p = t.binding.reader(l), + d = + null !== + (i = + null !== (n = o.optional.number(e.params.bufferSize).value) && void 0 !== n + ? n + : t.binding.defaultBufferSize && t.binding.defaultBufferSize(a.params)) && void 0 !== i + ? i + : 1, + c = o.optional.number(e.params.interval).value, + h = new fs({ reader: p, target: e.target, ticker: ws(e.document, c), value: Me(d) }), + u = o.optional.boolean(e.params.disabled).value, + v = o.optional.boolean(e.params.hidden).value, + m = t.controller({ + document: e.document, + params: a.params, + value: h.value, + viewProps: St.create({ disabled: u, hidden: v }) + }), + b = null !== (s = o.optional.string(e.params.label).value) && void 0 !== s ? s : e.target.key; + return new st(e.document, { binding: h, blade: W(), props: k.fromObject({ label: b }), valueController: m }); + })(s, { document: t, params: n, target: e }), + null + ); + if (i) return i; + throw new p({ context: { key: e.key }, type: 'nomatchingcontroller' }); + } + createBlade(t, e) { + const n = this.pluginsMap_.blades.reduce( + (n, i) => + n || + (function (t, e) { + const n = t.accept(e.params); + if (!n) return null; + const i = M.optional.boolean(e.params.disabled).value, + s = M.optional.boolean(e.params.hidden).value; + return t.controller({ + blade: W(), + document: e.document, + params: Object.assign(Object.assign({}, n.params), { disabled: i, hidden: s }), + viewProps: St.create({ disabled: i, hidden: s }) + }); + })(i, { document: t, params: e }), + null + ); + if (!n) throw new p({ type: 'nomatchingview', context: { params: e } }); + return n; + } + createBladeApi(t) { + if (t instanceof nt) return new et(t); + if (t instanceof st) return new it(t); + if (t instanceof mt) return new lt(t, this); + const e = this.pluginsMap_.blades.reduce((e, n) => e || n.api({ controller: t, pool: this }), null); + if (!e) throw p.shouldNeverHappen(); + return e; + } + } + class ys extends e { + constructor(t) { + super(t), + (this.emitter_ = new h()), + this.controller_.valueController.value.emitter.on('change', (t) => { + this.emitter_.emit('change', { event: new i(this, t.rawValue) }); + }); + } + get label() { + return this.controller_.props.get('label'); + } + set label(t) { + this.controller_.props.set('label', t); + } + get options() { + return this.controller_.valueController.props.get('options'); + } + set options(t) { + this.controller_.valueController.props.set('options', t); + } + get value() { + return this.controller_.valueController.value.rawValue; + } + set value(t) { + this.controller_.valueController.value.rawValue = t; + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + } + class Cs extends e { + constructor(t) { + super(t), + (this.emitter_ = new h()), + this.controller_.valueController.value.emitter.on('change', (t) => { + this.emitter_.emit('change', { event: new i(this, t.rawValue) }); + }); + } + get label() { + return this.controller_.props.get('label'); + } + set label(t) { + this.controller_.props.set('label', t); + } + get maxValue() { + return this.controller_.valueController.sliderController.props.get('maxValue'); + } + set maxValue(t) { + this.controller_.valueController.sliderController.props.set('maxValue', t); + } + get minValue() { + return this.controller_.valueController.sliderController.props.get('minValue'); + } + set minValue(t) { + this.controller_.valueController.sliderController.props.set('minValue', t); + } + get value() { + return this.controller_.valueController.value.rawValue; + } + set value(t) { + this.controller_.valueController.value.rawValue = t; + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + } + class Ps extends e { + constructor(t) { + super(t), + (this.emitter_ = new h()), + this.controller_.valueController.value.emitter.on('change', (t) => { + this.emitter_.emit('change', { event: new i(this, t.rawValue) }); + }); + } + get label() { + return this.controller_.props.get('label'); + } + set label(t) { + this.controller_.props.set('label', t); + } + get formatter() { + return this.controller_.valueController.props.get('formatter'); + } + set formatter(t) { + this.controller_.valueController.props.set('formatter', t); + } + get value() { + return this.controller_.valueController.value.rawValue; + } + set value(t) { + this.controller_.valueController.value.rawValue = t; + } + on(t, e) { + const n = e.bind(this); + return ( + this.emitter_.on(t, (t) => { + n(t.event); + }), + this + ); + } + } + const Es = { + id: 'list', + type: 'blade', + accept(t) { + const e = M, + n = L(t, { + options: e.required.custom(Je), + value: e.required.raw, + view: e.required.constant('list'), + label: e.optional.string + }); + return n ? { params: n } : null; + }, + controller(t) { + const e = new Yt(t.document, { + props: k.fromObject({ options: en(t.params.options) }), + value: E(t.params.value), + viewProps: t.viewProps + }); + return new wt(t.document, { blade: t.blade, props: k.fromObject({ label: t.params.label }), valueController: e }); + }, + api: (t) => (t.controller instanceof wt && t.controller.valueController instanceof Yt ? new ys(t.controller) : null) + }; + class ks extends pt { + constructor(t, e) { + super(t, e); + } + get element() { + return this.controller_.view.element; + } + importPreset(t) { + (function (t, e) { + t.forEach((t) => { + const n = e[t.presetKey]; + void 0 !== n && t.write(n); + }); + })( + this.controller_.rackController.rack.find(nt).map((t) => t.binding.target), + t + ), + this.refresh(); + } + exportPreset() { + return this.controller_.rackController.rack + .find(nt) + .map((t) => t.binding.target) + .reduce((t, e) => Object.assign(t, { [e.presetKey]: e.read() }), {}); + } + refresh() { + this.controller_.rackController.rack.find(nt).forEach((t) => { + t.binding.read(); + }), + this.controller_.rackController.rack.find(st).forEach((t) => { + t.binding.read(); + }); + } + } + class Vs extends _t { + constructor(t, e) { + super(t, { expanded: e.expanded, blade: e.blade, props: e.props, root: !0, viewProps: e.viewProps }); + } + } + const Ss = { + id: 'slider', + type: 'blade', + accept(t) { + const e = M, + n = L(t, { + max: e.required.number, + min: e.required.number, + view: e.required.constant('slider'), + format: e.optional.function, + label: e.optional.string, + value: e.optional.number + }); + return n ? { params: n } : null; + }, + controller(t) { + var e, n; + const i = null !== (e = t.params.value) && void 0 !== e ? e : 0, + s = new Xe(t.document, { + baseStep: 1, + parser: we, + sliderProps: k.fromObject({ maxValue: t.params.max, minValue: t.params.min }), + textProps: k.fromObject({ + draggingScale: an(void 0, i), + formatter: null !== (n = t.params.format) && void 0 !== n ? n : ye + }), + value: E(i), + viewProps: t.viewProps + }); + return new wt(t.document, { blade: t.blade, props: k.fromObject({ label: t.params.label }), valueController: s }); + }, + api: (t) => (t.controller instanceof wt && t.controller.valueController instanceof Xe ? new Cs(t.controller) : null) + }, + Ms = { + id: 'text', + type: 'blade', + accept(t) { + const e = M, + n = L(t, { + parse: e.required.function, + value: e.required.raw, + view: e.required.constant('text'), + format: e.optional.function, + label: e.optional.string + }); + return n ? { params: n } : null; + }, + controller(t) { + var e; + const n = new te(t.document, { + parser: t.params.parse, + props: k.fromObject({ formatter: null !== (e = t.params.format) && void 0 !== e ? e : (t) => String(t) }), + value: E(t.params.value), + viewProps: t.viewProps + }); + return new wt(t.document, { blade: t.blade, props: k.fromObject({ label: t.params.label }), valueController: n }); + }, + api: (t) => (t.controller instanceof wt && t.controller.valueController instanceof te ? new Ps(t.controller) : null) + }; + function Ls(t, e, n) { + if (t.querySelector(`style[data-tp-style=${e}]`)) return; + const i = t.createElement('style'); + (i.dataset.tpStyle = e), (i.textContent = n), t.head.appendChild(i); + } + const As = new (class { + constructor(t) { + const [e, n] = t.split('-'), + i = e.split('.'); + (this.major = parseInt(i[0], 10)), + (this.minor = parseInt(i[1], 10)), + (this.patch = parseInt(i[2], 10)), + (this.prerelease = null != n ? n : null); + } + toString() { + const t = [this.major, this.minor, this.patch].join('.'); + return null !== this.prerelease ? [t, this.prerelease].join('-') : t; + } + })('3.0.7'); + (t.BladeApi = e), + (t.ButtonApi = c), + (t.FolderApi = pt), + (t.InputBindingApi = et), + (t.ListApi = ys), + (t.MonitorBindingApi = it), + (t.Pane = class extends ks { + constructor(t) { + var e; + const n = t || {}, + i = null !== (e = n.document) && void 0 !== e ? e : R(), + s = (function () { + const t = new xs(); + return ( + [Ki, Yi, ts, es, Pi, gi, bi, mi, cn, ps, gs, bs, G, ft, Et, Ft].forEach((e) => { + t.register(e); + }), + t + ); + })(); + super( + new Vs(i, { expanded: n.expanded, blade: W(), props: k.fromObject({ title: n.title }), viewProps: St.create() }), + s + ), + (this.pool_ = s), + (this.containerElem_ = + n.container || + (function (t) { + const e = t.createElement('div'); + return e.classList.add(v('dfw')()), t.body && t.body.appendChild(e), e; + })(i)), + this.containerElem_.appendChild(this.element), + (this.doc_ = i), + (this.usesDefaultWrapper_ = !n.container), + this.setUpDefaultPlugins_(); + } + get document() { + if (!this.doc_) throw p.alreadyDisposed(); + return this.doc_; + } + dispose() { + const t = this.containerElem_; + if (!t) throw p.alreadyDisposed(); + if (this.usesDefaultWrapper_) { + const e = t.parentElement; + e && e.removeChild(t); + } + (this.containerElem_ = null), (this.doc_ = null), super.dispose(); + } + registerPlugin(t) { + ('plugin' in t ? [t.plugin] : 'plugins' in t ? t.plugins : []).forEach((t) => { + this.pool_.register(t), this.embedPluginStyle_(t); + }); + } + embedPluginStyle_(t) { + t.css && Ls(this.document, `plugin-${t.id}`, t.css); + } + setUpDefaultPlugins_() { + Ls( + this.document, + 'default', + ".tp-lstv_s,.tp-btnv_b,.tp-p2dv_b,.tp-colswv_sw,.tp-p2dpv_p,.tp-txtv_i,.tp-grlv_g,.tp-sglv_i,.tp-mllv_i,.tp-fldv_b,.tp-rotv_b,.tp-ckbv_i,.tp-coltxtv_ms,.tp-tbiv_b{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border-width:0;font-family:inherit;font-size:inherit;font-weight:inherit;margin:0;outline:none;padding:0}.tp-lstv_s,.tp-btnv_b,.tp-p2dv_b{background-color:var(--btn-bg);border-radius:var(--elm-br);color:var(--btn-fg);cursor:pointer;display:block;font-weight:bold;height:var(--bld-us);line-height:var(--bld-us);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tp-lstv_s:hover,.tp-btnv_b:hover,.tp-p2dv_b:hover{background-color:var(--btn-bg-h)}.tp-lstv_s:focus,.tp-btnv_b:focus,.tp-p2dv_b:focus{background-color:var(--btn-bg-f)}.tp-lstv_s:active,.tp-btnv_b:active,.tp-p2dv_b:active{background-color:var(--btn-bg-a)}.tp-lstv_s:disabled,.tp-btnv_b:disabled,.tp-p2dv_b:disabled{opacity:0.5}.tp-colswv_sw,.tp-p2dpv_p,.tp-txtv_i{background-color:var(--in-bg);border-radius:var(--elm-br);box-sizing:border-box;color:var(--in-fg);font-family:inherit;height:var(--bld-us);line-height:var(--bld-us);min-width:0;width:100%}.tp-colswv_sw:hover,.tp-p2dpv_p:hover,.tp-txtv_i:hover{background-color:var(--in-bg-h)}.tp-colswv_sw:focus,.tp-p2dpv_p:focus,.tp-txtv_i:focus{background-color:var(--in-bg-f)}.tp-colswv_sw:active,.tp-p2dpv_p:active,.tp-txtv_i:active{background-color:var(--in-bg-a)}.tp-colswv_sw:disabled,.tp-p2dpv_p:disabled,.tp-txtv_i:disabled{opacity:0.5}.tp-grlv_g,.tp-sglv_i,.tp-mllv_i{background-color:var(--mo-bg);border-radius:var(--elm-br);box-sizing:border-box;color:var(--mo-fg);height:var(--bld-us);width:100%}.tp-rotv{--font-family: var(--tp-font-family, Roboto Mono,Source Code Pro,Menlo,Courier,monospace);--bs-br: var(--tp-base-border-radius, 6px);--cnt-h-p: var(--tp-container-horizontal-padding, 4px);--cnt-v-p: var(--tp-container-vertical-padding, 4px);--elm-br: var(--tp-element-border-radius, 2px);--bld-s: var(--tp-blade-spacing, 4px);--bld-us: var(--tp-blade-unit-size, 20px);--bs-bg: var(--tp-base-background-color, #2f3137);--bs-sh: var(--tp-base-shadow-color, rgba(0,0,0,0.2));--btn-bg: var(--tp-button-background-color, #adafb8);--btn-bg-a: var(--tp-button-background-color-active, #d6d7db);--btn-bg-f: var(--tp-button-background-color-focus, #c8cad0);--btn-bg-h: var(--tp-button-background-color-hover, #bbbcc4);--btn-fg: var(--tp-button-foreground-color, #2f3137);--cnt-bg: var(--tp-container-background-color, rgba(187,188,196,0.1));--cnt-bg-a: var(--tp-container-background-color-active, rgba(187,188,196,0.25));--cnt-bg-f: var(--tp-container-background-color-focus, rgba(187,188,196,0.2));--cnt-bg-h: var(--tp-container-background-color-hover, rgba(187,188,196,0.15));--cnt-fg: var(--tp-container-foreground-color, #bbbcc4);--in-bg: var(--tp-input-background-color, rgba(187,188,196,0.1));--in-bg-a: var(--tp-input-background-color-active, rgba(187,188,196,0.25));--in-bg-f: var(--tp-input-background-color-focus, rgba(187,188,196,0.2));--in-bg-h: var(--tp-input-background-color-hover, rgba(187,188,196,0.15));--in-fg: var(--tp-input-foreground-color, #bbbcc4);--lbl-fg: var(--tp-label-foreground-color, rgba(187,188,196,0.7));--mo-bg: var(--tp-monitor-background-color, rgba(0,0,0,0.2));--mo-fg: var(--tp-monitor-foreground-color, rgba(187,188,196,0.7));--grv-fg: var(--tp-groove-foreground-color, rgba(0,0,0,0.2))}.tp-fldv_c>.tp-cntv.tp-v-lst,.tp-tabv_c .tp-brkv>.tp-cntv.tp-v-lst,.tp-rotv_c>.tp-cntv.tp-v-lst{margin-bottom:calc(-1 * var(--cnt-v-p))}.tp-fldv_c>.tp-fldv.tp-v-lst .tp-fldv_c,.tp-tabv_c .tp-brkv>.tp-fldv.tp-v-lst .tp-fldv_c,.tp-rotv_c>.tp-fldv.tp-v-lst .tp-fldv_c{border-bottom-left-radius:0}.tp-fldv_c>.tp-fldv.tp-v-lst .tp-fldv_b,.tp-tabv_c .tp-brkv>.tp-fldv.tp-v-lst .tp-fldv_b,.tp-rotv_c>.tp-fldv.tp-v-lst .tp-fldv_b{border-bottom-left-radius:0}.tp-fldv_c>*:not(.tp-v-fst),.tp-tabv_c .tp-brkv>*:not(.tp-v-fst),.tp-rotv_c>*:not(.tp-v-fst){margin-top:var(--bld-s)}.tp-fldv_c>.tp-sprv:not(.tp-v-fst),.tp-tabv_c .tp-brkv>.tp-sprv:not(.tp-v-fst),.tp-rotv_c>.tp-sprv:not(.tp-v-fst),.tp-fldv_c>.tp-cntv:not(.tp-v-fst),.tp-tabv_c .tp-brkv>.tp-cntv:not(.tp-v-fst),.tp-rotv_c>.tp-cntv:not(.tp-v-fst){margin-top:var(--cnt-v-p)}.tp-fldv_c>.tp-sprv+*:not(.tp-v-hidden),.tp-tabv_c .tp-brkv>.tp-sprv+*:not(.tp-v-hidden),.tp-rotv_c>.tp-sprv+*:not(.tp-v-hidden),.tp-fldv_c>.tp-cntv+*:not(.tp-v-hidden),.tp-tabv_c .tp-brkv>.tp-cntv+*:not(.tp-v-hidden),.tp-rotv_c>.tp-cntv+*:not(.tp-v-hidden){margin-top:var(--cnt-v-p)}.tp-fldv_c>.tp-sprv:not(.tp-v-hidden)+.tp-sprv,.tp-tabv_c .tp-brkv>.tp-sprv:not(.tp-v-hidden)+.tp-sprv,.tp-rotv_c>.tp-sprv:not(.tp-v-hidden)+.tp-sprv,.tp-fldv_c>.tp-cntv:not(.tp-v-hidden)+.tp-cntv,.tp-tabv_c .tp-brkv>.tp-cntv:not(.tp-v-hidden)+.tp-cntv,.tp-rotv_c>.tp-cntv:not(.tp-v-hidden)+.tp-cntv{margin-top:0}.tp-fldv_c>.tp-cntv,.tp-tabv_c .tp-brkv>.tp-cntv{margin-left:4px}.tp-fldv_c>.tp-fldv>.tp-fldv_b,.tp-tabv_c .tp-brkv>.tp-fldv>.tp-fldv_b{border-top-left-radius:var(--elm-br);border-bottom-left-radius:var(--elm-br)}.tp-fldv_c>.tp-fldv.tp-fldv-expanded>.tp-fldv_b,.tp-tabv_c .tp-brkv>.tp-fldv.tp-fldv-expanded>.tp-fldv_b{border-bottom-left-radius:0}.tp-fldv_c .tp-fldv>.tp-fldv_c,.tp-tabv_c .tp-brkv .tp-fldv>.tp-fldv_c{border-bottom-left-radius:var(--elm-br)}.tp-fldv_c>.tp-tabv>.tp-tabv_i,.tp-tabv_c .tp-brkv>.tp-tabv>.tp-tabv_i{border-top-left-radius:var(--elm-br)}.tp-fldv_c .tp-tabv>.tp-tabv_c,.tp-tabv_c .tp-brkv .tp-tabv>.tp-tabv_c{border-bottom-left-radius:var(--elm-br)}.tp-fldv_b,.tp-rotv_b{background-color:var(--cnt-bg);color:var(--cnt-fg);cursor:pointer;display:block;height:calc(var(--bld-us) + 4px);line-height:calc(var(--bld-us) + 4px);overflow:hidden;padding-left:var(--cnt-h-p);padding-right:calc(2px * 2 + var(--bld-us) + var(--cnt-h-p));position:relative;text-align:left;text-overflow:ellipsis;white-space:nowrap;width:100%;transition:border-radius .2s ease-in-out .2s}.tp-fldv_b:hover,.tp-rotv_b:hover{background-color:var(--cnt-bg-h)}.tp-fldv_b:focus,.tp-rotv_b:focus{background-color:var(--cnt-bg-f)}.tp-fldv_b:active,.tp-rotv_b:active{background-color:var(--cnt-bg-a)}.tp-fldv_b:disabled,.tp-rotv_b:disabled{opacity:0.5}.tp-fldv_m,.tp-rotv_m{background:linear-gradient(to left, var(--cnt-fg), var(--cnt-fg) 2px, transparent 2px, transparent 4px, var(--cnt-fg) 4px);border-radius:2px;bottom:0;content:'';display:block;height:6px;right:calc(var(--cnt-h-p) + (var(--bld-us) + 4px - 6px) / 2 - 2px);margin:auto;opacity:0.5;position:absolute;top:0;transform:rotate(90deg);transition:transform .2s ease-in-out;width:6px}.tp-fldv.tp-fldv-expanded>.tp-fldv_b>.tp-fldv_m,.tp-rotv.tp-rotv-expanded .tp-rotv_m{transform:none}.tp-fldv_c,.tp-rotv_c{box-sizing:border-box;height:0;opacity:0;overflow:hidden;padding-bottom:0;padding-top:0;position:relative;transition:height .2s ease-in-out,opacity .2s linear,padding .2s ease-in-out}.tp-fldv.tp-fldv-cpl:not(.tp-fldv-expanded)>.tp-fldv_c,.tp-rotv.tp-rotv-cpl:not(.tp-rotv-expanded) .tp-rotv_c{display:none}.tp-fldv.tp-fldv-expanded>.tp-fldv_c,.tp-rotv.tp-rotv-expanded .tp-rotv_c{opacity:1;padding-bottom:var(--cnt-v-p);padding-top:var(--cnt-v-p);transform:none;overflow:visible;transition:height .2s ease-in-out,opacity .2s linear .2s,padding .2s ease-in-out}.tp-coltxtv_m,.tp-lstv{position:relative}.tp-lstv_s{padding:0 20px 0 4px;width:100%}.tp-coltxtv_mm,.tp-lstv_m{bottom:0;margin:auto;pointer-events:none;position:absolute;right:2px;top:0}.tp-coltxtv_mm svg,.tp-lstv_m svg{bottom:0;height:16px;margin:auto;position:absolute;right:0;top:0;width:16px}.tp-coltxtv_mm svg path,.tp-lstv_m svg path{fill:currentColor}.tp-coltxtv_w,.tp-pndtxtv{display:flex}.tp-coltxtv_c,.tp-pndtxtv_a{width:100%}.tp-coltxtv_c+.tp-coltxtv_c,.tp-pndtxtv_a+.tp-coltxtv_c,.tp-coltxtv_c+.tp-pndtxtv_a,.tp-pndtxtv_a+.tp-pndtxtv_a{margin-left:2px}.tp-btnv_b{width:100%}.tp-btnv_t{text-align:center}.tp-ckbv_l{display:block;position:relative}.tp-ckbv_i{left:0;opacity:0;position:absolute;top:0}.tp-ckbv_w{background-color:var(--in-bg);border-radius:var(--elm-br);cursor:pointer;display:block;height:var(--bld-us);position:relative;width:var(--bld-us)}.tp-ckbv_w svg{bottom:0;display:block;height:16px;left:0;margin:auto;opacity:0;position:absolute;right:0;top:0;width:16px}.tp-ckbv_w svg path{fill:none;stroke:var(--in-fg);stroke-width:2}.tp-ckbv_i:hover+.tp-ckbv_w{background-color:var(--in-bg-h)}.tp-ckbv_i:focus+.tp-ckbv_w{background-color:var(--in-bg-f)}.tp-ckbv_i:active+.tp-ckbv_w{background-color:var(--in-bg-a)}.tp-ckbv_i:checked+.tp-ckbv_w svg{opacity:1}.tp-ckbv.tp-v-disabled .tp-ckbv_w{opacity:0.5}.tp-colv{position:relative}.tp-colv_h{display:flex}.tp-colv_s{flex-grow:0;flex-shrink:0;width:var(--bld-us)}.tp-colv_t{flex:1;margin-left:4px}.tp-colv_p{height:0;margin-top:0;opacity:0;overflow:hidden;transition:height .2s ease-in-out,opacity .2s linear,margin .2s ease-in-out}.tp-colv.tp-colv-cpl .tp-colv_p{overflow:visible}.tp-colv.tp-colv-expanded .tp-colv_p{margin-top:var(--bld-s);opacity:1}.tp-colv .tp-popv{left:calc(-1 * var(--cnt-h-p));right:calc(-1 * var(--cnt-h-p));top:var(--bld-us)}.tp-colpv_h,.tp-colpv_ap{margin-left:6px;margin-right:6px}.tp-colpv_h{margin-top:var(--bld-s)}.tp-colpv_rgb{display:flex;margin-top:var(--bld-s);width:100%}.tp-colpv_a{display:flex;margin-top:var(--cnt-v-p);padding-top:calc(var(--cnt-v-p) + 2px);position:relative}.tp-colpv_a:before{background-color:var(--grv-fg);content:'';height:2px;left:calc(-1 * var(--cnt-h-p));position:absolute;right:calc(-1 * var(--cnt-h-p));top:0}.tp-colpv_ap{align-items:center;display:flex;flex:3}.tp-colpv_at{flex:1;margin-left:4px}.tp-svpv{border-radius:var(--elm-br);outline:none;overflow:hidden;position:relative}.tp-svpv_c{cursor:crosshair;display:block;height:calc(var(--bld-us) * 4);width:100%}.tp-svpv_m{border-radius:100%;border:rgba(255,255,255,0.75) solid 2px;box-sizing:border-box;filter:drop-shadow(0 0 1px rgba(0,0,0,0.3));height:12px;margin-left:-6px;margin-top:-6px;pointer-events:none;position:absolute;width:12px}.tp-svpv:focus .tp-svpv_m{border-color:#fff}.tp-hplv{cursor:pointer;height:var(--bld-us);outline:none;position:relative}.tp-hplv_c{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAABCAYAAABubagXAAAAQ0lEQVQoU2P8z8Dwn0GCgQEDi2OK/RBgYHjBgIpfovFh8j8YBIgzFGQxuqEgPhaDOT5gOhPkdCxOZeBg+IDFZZiGAgCaSSMYtcRHLgAAAABJRU5ErkJggg==);background-position:left top;background-repeat:no-repeat;background-size:100% 100%;border-radius:2px;display:block;height:4px;left:0;margin-top:-2px;position:absolute;top:50%;width:100%}.tp-hplv_m{border-radius:var(--elm-br);border:rgba(255,255,255,0.75) solid 2px;box-shadow:0 0 2px rgba(0,0,0,0.1);box-sizing:border-box;height:12px;left:50%;margin-left:-6px;margin-top:-6px;pointer-events:none;position:absolute;top:50%;width:12px}.tp-hplv:focus .tp-hplv_m{border-color:#fff}.tp-aplv{cursor:pointer;height:var(--bld-us);outline:none;position:relative;width:100%}.tp-aplv_b{background-color:#fff;background-image:linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%),linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%);background-size:4px 4px;background-position:0 0,2px 2px;border-radius:2px;display:block;height:4px;left:0;margin-top:-2px;overflow:hidden;position:absolute;top:50%;width:100%}.tp-aplv_c{bottom:0;left:0;position:absolute;right:0;top:0}.tp-aplv_m{background-color:#fff;background-image:linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%),linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%);background-size:12px 12px;background-position:0 0,6px 6px;border-radius:var(--elm-br);box-shadow:0 0 2px rgba(0,0,0,0.1);height:12px;left:50%;margin-left:-6px;margin-top:-6px;overflow:hidden;pointer-events:none;position:absolute;top:50%;width:12px}.tp-aplv_p{border-radius:var(--elm-br);border:rgba(255,255,255,0.75) solid 2px;box-sizing:border-box;bottom:0;left:0;position:absolute;right:0;top:0}.tp-aplv:focus .tp-aplv_p{border-color:#fff}.tp-colswv{background-color:#fff;background-image:linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%),linear-gradient(to top right, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%);background-size:10px 10px;background-position:0 0,5px 5px;border-radius:var(--elm-br)}.tp-colswv.tp-v-disabled{opacity:0.5}.tp-colswv_b{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border-width:0;cursor:pointer;display:block;height:var(--bld-us);left:0;margin:0;outline:none;padding:0;position:absolute;top:0;width:var(--bld-us)}.tp-colswv_b:focus::after{border:rgba(255,255,255,0.75) solid 2px;border-radius:var(--elm-br);bottom:0;content:'';display:block;left:0;position:absolute;right:0;top:0}.tp-coltxtv{display:flex;width:100%}.tp-coltxtv_m{margin-right:4px}.tp-coltxtv_ms{border-radius:var(--elm-br);color:var(--lbl-fg);cursor:pointer;height:var(--bld-us);line-height:var(--bld-us);padding:0 18px 0 4px}.tp-coltxtv_ms:hover{background-color:var(--in-bg-h)}.tp-coltxtv_ms:focus{background-color:var(--in-bg-f)}.tp-coltxtv_ms:active{background-color:var(--in-bg-a)}.tp-coltxtv_mm{color:var(--lbl-fg)}.tp-coltxtv_w{flex:1}.tp-dfwv{position:absolute;top:8px;right:8px;width:256px}.tp-fldv.tp-fldv-not .tp-fldv_b{display:none}.tp-fldv_t{padding-left:4px}.tp-fldv_c{border-left:var(--cnt-bg) solid 4px}.tp-fldv_b:hover+.tp-fldv_c{border-left-color:var(--cnt-bg-h)}.tp-fldv_b:focus+.tp-fldv_c{border-left-color:var(--cnt-bg-f)}.tp-fldv_b:active+.tp-fldv_c{border-left-color:var(--cnt-bg-a)}.tp-grlv{position:relative}.tp-grlv_g{display:block;height:calc(var(--bld-us) * 3)}.tp-grlv_g polyline{fill:none;stroke:var(--mo-fg);stroke-linejoin:round}.tp-grlv_t{margin-top:-4px;transition:left 0.05s, top 0.05s;visibility:hidden}.tp-grlv_t.tp-grlv_t-a{visibility:visible}.tp-grlv_t.tp-grlv_t-in{transition:none}.tp-grlv.tp-v-disabled .tp-grlv_g{opacity:0.5}.tp-grlv .tp-ttv{background-color:var(--mo-fg)}.tp-grlv .tp-ttv::before{border-top-color:var(--mo-fg)}.tp-lblv{align-items:center;display:flex;line-height:1.3;padding-left:var(--cnt-h-p);padding-right:var(--cnt-h-p)}.tp-lblv.tp-lblv-nol{display:block}.tp-lblv_l{color:var(--lbl-fg);flex:1;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;overflow:hidden;padding-left:4px;padding-right:16px}.tp-lblv.tp-v-disabled .tp-lblv_l{opacity:0.5}.tp-lblv.tp-lblv-nol .tp-lblv_l{display:none}.tp-lblv_v{align-self:flex-start;flex-grow:0;flex-shrink:0;width:160px}.tp-lblv.tp-lblv-nol .tp-lblv_v{width:100%}.tp-lstv_s{padding:0 20px 0 4px;width:100%}.tp-lstv_m{color:var(--btn-fg)}.tp-sglv_i{padding:0 4px}.tp-sglv.tp-v-disabled .tp-sglv_i{opacity:0.5}.tp-mllv_i{display:block;height:calc(var(--bld-us) * 3);line-height:var(--bld-us);padding:0 4px;resize:none;white-space:pre}.tp-mllv.tp-v-disabled .tp-mllv_i{opacity:0.5}.tp-p2dv{position:relative}.tp-p2dv_h{display:flex}.tp-p2dv_b{height:var(--bld-us);margin-right:4px;position:relative;width:var(--bld-us)}.tp-p2dv_b svg{display:block;height:16px;left:50%;margin-left:-8px;margin-top:-8px;position:absolute;top:50%;width:16px}.tp-p2dv_b svg path{stroke:currentColor;stroke-width:2}.tp-p2dv_b svg circle{fill:currentColor}.tp-p2dv_t{flex:1}.tp-p2dv_p{height:0;margin-top:0;opacity:0;overflow:hidden;transition:height .2s ease-in-out,opacity .2s linear,margin .2s ease-in-out}.tp-p2dv.tp-p2dv-expanded .tp-p2dv_p{margin-top:var(--bld-s);opacity:1}.tp-p2dv .tp-popv{left:calc(-1 * var(--cnt-h-p));right:calc(-1 * var(--cnt-h-p));top:var(--bld-us)}.tp-p2dpv{padding-left:calc(var(--bld-us) + 4px)}.tp-p2dpv_p{cursor:crosshair;height:0;overflow:hidden;padding-bottom:100%;position:relative}.tp-p2dpv_g{display:block;height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%}.tp-p2dpv_ax{opacity:0.1;stroke:var(--in-fg);stroke-dasharray:1}.tp-p2dpv_l{opacity:0.5;stroke:var(--in-fg);stroke-dasharray:1}.tp-p2dpv_m{border:var(--in-fg) solid 1px;border-radius:50%;box-sizing:border-box;height:4px;margin-left:-2px;margin-top:-2px;position:absolute;width:4px}.tp-p2dpv_p:focus .tp-p2dpv_m{background-color:var(--in-fg);border-width:0}.tp-popv{background-color:var(--bs-bg);border-radius:6px;box-shadow:0 2px 4px var(--bs-sh);display:none;max-width:168px;padding:var(--cnt-v-p) var(--cnt-h-p);position:absolute;visibility:hidden;z-index:1000}.tp-popv.tp-popv-v{display:block;visibility:visible}.tp-sprv_r{background-color:var(--grv-fg);border-width:0;display:block;height:2px;margin:0;width:100%}.tp-sldv.tp-v-disabled{opacity:0.5}.tp-sldv_t{box-sizing:border-box;cursor:pointer;height:var(--bld-us);margin:0 6px;outline:none;position:relative}.tp-sldv_t::before{background-color:var(--in-bg);border-radius:1px;bottom:0;content:'';display:block;height:2px;left:0;margin:auto;position:absolute;right:0;top:0}.tp-sldv_k{height:100%;left:0;position:absolute;top:0}.tp-sldv_k::before{background-color:var(--in-fg);border-radius:1px;bottom:0;content:'';display:block;height:2px;left:0;margin-bottom:auto;margin-top:auto;position:absolute;right:0;top:0}.tp-sldv_k::after{background-color:var(--btn-bg);border-radius:var(--elm-br);bottom:0;content:'';display:block;height:12px;margin-bottom:auto;margin-top:auto;position:absolute;right:-6px;top:0;width:12px}.tp-sldv_t:hover .tp-sldv_k::after{background-color:var(--btn-bg-h)}.tp-sldv_t:focus .tp-sldv_k::after{background-color:var(--btn-bg-f)}.tp-sldv_t:active .tp-sldv_k::after{background-color:var(--btn-bg-a)}.tp-sldtxtv{display:flex}.tp-sldtxtv_s{flex:2}.tp-sldtxtv_t{flex:1;margin-left:4px}.tp-tabv.tp-v-disabled{opacity:0.5}.tp-tabv_i{align-items:flex-end;display:flex;overflow:hidden}.tp-tabv.tp-tabv-nop .tp-tabv_i{height:calc(var(--bld-us) + 4px);position:relative}.tp-tabv.tp-tabv-nop .tp-tabv_i::before{background-color:var(--cnt-bg);bottom:0;content:'';height:2px;left:0;position:absolute;right:0}.tp-tabv_c{border-left:var(--cnt-bg) solid 4px;padding-bottom:var(--cnt-v-p);padding-top:var(--cnt-v-p)}.tp-tbiv{flex:1;min-width:0;position:relative}.tp-tbiv+.tp-tbiv{margin-left:2px}.tp-tbiv+.tp-tbiv::before{background-color:var(--cnt-bg);bottom:0;content:'';height:2px;left:-2px;position:absolute;width:2px}.tp-tbiv_b{background-color:var(--cnt-bg);display:block;padding-left:calc(var(--cnt-h-p) + 4px);padding-right:calc(var(--cnt-h-p) + 4px);width:100%}.tp-tbiv_b:hover{background-color:var(--cnt-bg-h)}.tp-tbiv_b:focus{background-color:var(--cnt-bg-f)}.tp-tbiv_b:active{background-color:var(--cnt-bg-a)}.tp-tbiv_b:disabled{opacity:0.5}.tp-tbiv_t{color:var(--cnt-fg);height:calc(var(--bld-us) + 4px);line-height:calc(var(--bld-us) + 4px);opacity:0.5;overflow:hidden;text-overflow:ellipsis}.tp-tbiv.tp-tbiv-sel .tp-tbiv_t{opacity:1}.tp-txtv{position:relative}.tp-txtv_i{padding:0 4px}.tp-txtv.tp-txtv-fst .tp-txtv_i{border-bottom-right-radius:0;border-top-right-radius:0}.tp-txtv.tp-txtv-mid .tp-txtv_i{border-radius:0}.tp-txtv.tp-txtv-lst .tp-txtv_i{border-bottom-left-radius:0;border-top-left-radius:0}.tp-txtv.tp-txtv-num .tp-txtv_i{text-align:right}.tp-txtv.tp-txtv-drg .tp-txtv_i{opacity:0.3}.tp-txtv_k{cursor:pointer;height:100%;left:-3px;position:absolute;top:0;width:12px}.tp-txtv_k::before{background-color:var(--in-fg);border-radius:1px;bottom:0;content:'';height:calc(var(--bld-us) - 4px);left:50%;margin-bottom:auto;margin-left:-1px;margin-top:auto;opacity:0.1;position:absolute;top:0;transition:border-radius 0.1s, height 0.1s, transform 0.1s, width 0.1s;width:2px}.tp-txtv_k:hover::before,.tp-txtv.tp-txtv-drg .tp-txtv_k::before{opacity:1}.tp-txtv.tp-txtv-drg .tp-txtv_k::before{border-radius:50%;height:4px;transform:translateX(-1px);width:4px}.tp-txtv_g{bottom:0;display:block;height:8px;left:50%;margin:auto;overflow:visible;pointer-events:none;position:absolute;top:0;visibility:hidden;width:100%}.tp-txtv.tp-txtv-drg .tp-txtv_g{visibility:visible}.tp-txtv_gb{fill:none;stroke:var(--in-fg);stroke-dasharray:1}.tp-txtv_gh{fill:none;stroke:var(--in-fg)}.tp-txtv .tp-ttv{margin-left:6px;visibility:hidden}.tp-txtv.tp-txtv-drg .tp-ttv{visibility:visible}.tp-ttv{background-color:var(--in-fg);border-radius:var(--elm-br);color:var(--bs-bg);padding:2px 4px;pointer-events:none;position:absolute;transform:translate(-50%, -100%)}.tp-ttv::before{border-color:var(--in-fg) transparent transparent transparent;border-style:solid;border-width:2px;box-sizing:border-box;content:'';font-size:0.9em;height:4px;left:50%;margin-left:-2px;position:absolute;top:100%;width:4px}.tp-rotv{background-color:var(--bs-bg);border-radius:var(--bs-br);box-shadow:0 2px 4px var(--bs-sh);font-family:var(--font-family);font-size:11px;font-weight:500;line-height:1;text-align:left}.tp-rotv_b{border-bottom-left-radius:var(--bs-br);border-bottom-right-radius:var(--bs-br);border-top-left-radius:var(--bs-br);border-top-right-radius:var(--bs-br);padding-left:calc(2px * 2 + var(--bld-us) + var(--cnt-h-p));text-align:center}.tp-rotv.tp-rotv-expanded .tp-rotv_b{border-bottom-left-radius:0;border-bottom-right-radius:0}.tp-rotv.tp-rotv-not .tp-rotv_b{display:none}.tp-rotv_c>.tp-fldv.tp-v-lst>.tp-fldv_c,.tp-rotv_c>.tp-tabv.tp-v-lst>.tp-tabv_c{border-bottom-left-radius:var(--bs-br);border-bottom-right-radius:var(--bs-br)}.tp-rotv_c>.tp-fldv.tp-v-lst:not(.tp-fldv-expanded)>.tp-fldv_b{border-bottom-left-radius:var(--bs-br);border-bottom-right-radius:var(--bs-br)}.tp-rotv_c .tp-fldv.tp-v-vlst:not(.tp-fldv-expanded)>.tp-fldv_b{border-bottom-right-radius:var(--bs-br)}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-fldv.tp-v-fst{margin-top:calc(-1 * var(--cnt-v-p))}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-fldv.tp-v-fst>.tp-fldv_b{border-top-left-radius:var(--bs-br);border-top-right-radius:var(--bs-br)}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-tabv.tp-v-fst{margin-top:calc(-1 * var(--cnt-v-p))}.tp-rotv.tp-rotv-not .tp-rotv_c>.tp-tabv.tp-v-fst>.tp-tabv_i{border-top-left-radius:var(--bs-br);border-top-right-radius:var(--bs-br)}.tp-rotv.tp-v-disabled,.tp-rotv .tp-v-disabled{pointer-events:none}.tp-rotv.tp-v-hidden,.tp-rotv .tp-v-hidden{display:none}" + ), + this.pool_.getAll().forEach((t) => { + this.embedPluginStyle_(t); + }), + this.registerPlugin({ plugins: [Ss, Es, Ft, Ms] }); + } + }), + (t.SeparatorApi = xt), + (t.SliderApi = Cs), + (t.TabApi = Dt), + (t.TabPageApi = Tt), + (t.TextApi = Ps), + (t.TpChangeEvent = i), + (t.VERSION = As), + Object.defineProperty(t, '__esModule', { value: !0 }); + })(e); + }, + excalibur: (e) => { + 'use strict'; + e.exports = t; + } + }, + n = {}; + function i(t) { + var s = n[t]; + if (void 0 !== s) return s.exports; + var o = (n[t] = { exports: {} }); + return e[t].call(o.exports, o, o.exports, i), o.exports; + } + (i.n = (t) => { + var e = t && t.__esModule ? () => t.default : () => t; + return i.d(e, { a: e }), e; + }), + (i.d = (t, e) => { + for (var n in e) i.o(e, n) && !i.o(t, n) && Object.defineProperty(t, n, { enumerable: !0, get: e[n] }); + }), + (i.o = (t, e) => Object.prototype.hasOwnProperty.call(t, e)), + (i.r = (t) => { + 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), + Object.defineProperty(t, '__esModule', { value: !0 }); + }); + var s = {}; + return ( + (() => { + 'use strict'; + i.r(s), i.d(s, { DevTool: () => o }); + var t = i('excalibur'), + e = i('./node_modules/tweakpane/dist/tweakpane.js'), + n = i('./picker-system.ts'); + class o { + constructor(t) { + (this.engine = t), + (this.pointerPos = { x: 0, y: 0 }), + (this.highlightedEntities = [-1]), + (this.selectedEntity = null), + (this.selectedEntityId = -1), + (this.pane = new e.Pane({ title: 'Excalibur Dev Tools', expanded: !0 })); + const n = document.createElement('style'); + (n.innerText = '.excalibur-tweakpane-custom { width: 405px; }'), + document.head.appendChild(n), + this.pane.element.parentElement.classList.add('excalibur-tweakpane-custom'), + this._buildMain(), + (this.tabs = this.pane.addTab({ + pages: [ + { title: 'Entity' }, + { title: 'Screen' }, + { title: 'Camera' }, + { title: 'Clock' }, + { title: 'Timers' }, + { title: 'Physics' }, + { title: 'Settings' } + ] + })), + (this.selectedEntityTab = this.tabs.pages[0]), + (this.screenTab = this.tabs.pages[1]), + (this.cameraTab = this.tabs.pages[2]), + (this.clockTab = this.tabs.pages[3]), + (this.timerTab = this.tabs.pages[4]), + (this.physicsTab = this.tabs.pages[5]), + (this.debugTab = this.tabs.pages[6]), + this._installPickerSystemIfNeeded(t.currentScene), + (t.debug.transform.showPosition = !0), + (t.debug.entity.showName = !0), + (this.selectedEntityFolder = this.selectedEntityTab.addFolder({ title: 'Selected' })), + this._buildScreenTab(), + this._buildCameraTab(), + this._buildClockTab(), + this._buildTimersTab(), + this._buildPhysicsTab(), + this._buildDebugSettingsTab(), + setInterval(() => { + this.update(this); + }, 30), + this.addListeners(); + } + addListeners() { + this.engine.canvas.addEventListener('click', () => { + -1 !== this.highlightedEntities[0] && this.selectEntityById(this.highlightedEntities[0]); + }); + } + selectEntityById(e) { + const n = this.engine; + (this.selectedEntityId = e), + (this.selectedEntity = n.currentScene.world.entityManager.getById(e)), + this._buildEntityUI(this.selectedEntity); + const i = this.selectedEntity.get(t.TransformComponent); + this._buildTransformUI(i); + const s = this.selectedEntity.get(t.MotionComponent); + if ((this._buildMotionUI(s), this.selectedEntity instanceof t.ParticleEmitter)) + this._buildParticleEmitterUI(this.selectedEntity); + else { + const e = this.selectedEntity.get(t.GraphicsComponent); + this._buildGraphicsUI(e); + const n = this.selectedEntity.get(t.ColliderComponent), + i = this.selectedEntity.get(t.BodyComponent); + this._buildColliderUI(n, i); + } + } + update(t) { + const e = t.engine, + n = e.input.pointers.primary.lastWorldPos; + (this.pointerPos.x = n.x), (this.pointerPos.y = n.y), this.pointerPosInput.refresh(); + const i = [...this.pickerSystem.lastFrameEntityToPointers.keys(), ...this.pickerSystem.currentFrameEntityToPointers.keys()]; + 0 === i.length && (i.push(-1), i.push(this.selectedEntityId)), + (this.highlightedEntities = i), + (e.debug.filter.useFilter = !0), + (e.debug.filter.ids = i), + (this.currentResolution.width === e.screen.resolution.width && + this.currentResolution.height === e.screen.resolution.height && + this.currentViewport.width === e.screen.viewport.width && + this.currentViewport.height === e.screen.viewport.height) || + (this.resolutionText.dispose(), + this.viewportText.dispose(), + (this.resolutionText = this.screenFolder.addBlade({ + view: 'text', + label: 'resolution', + value: `(${e.screen.resolution.width}x${e.screen.resolution.height})`, + parse: (t) => String(t), + index: 0 + })), + (this.viewportText = this.screenFolder.addBlade({ + view: 'text', + label: 'viewport', + value: `(${e.screen.viewport.width.toFixed(0)}x${e.screen.viewport.height.toFixed(0)})`, + parse: (t) => String(t), + index: 1 + }))), + this._buildTimersTab(); + } + _installPickerSystemIfNeeded(t) { + (this.pickerSystem = t.world.systemManager.get(n.PickerSystem)), + this.pickerSystem || ((this.pickerSystem = new n.PickerSystem()), t.world.systemManager.addSystem(this.pickerSystem)); + } + _buildMain() { + this.pane.addInput({ debug: !1 }, 'debug').on('change', () => { + this.engine.toggleDebug(); + }), + this.pane.addMonitor(this.engine.clock.fpsSampler, 'fps', { view: 'graph', label: 'fps (0 - 120)', min: 0, max: 120 }); + let t, + e = '', + n = []; + for (let t in this.engine.scenes) this.engine.currentScene === this.engine.scenes[t] && (e = t), n.push({ text: t, value: t }); + this.pane.addBlade({ view: 'list', label: 'current scene', options: n, value: e }).on('change', (e) => { + this.engine.goToScene(e.value), + this._installPickerSystemIfNeeded(this.engine.currentScene), + t.dispose(), + (t = this.pane.addBlade({ + view: 'text', + label: 'number of entities', + value: this.engine.currentScene.world.entityManager.entities.length, + parse: (t) => String(t), + index: 3 + })); + }), + (t = this.pane.addBlade({ + view: 'text', + label: 'number of entities', + value: this.engine.currentScene.world.entityManager.entities.length, + parse: (t) => String(t), + index: 3 + })), + (this.pointerPos = { x: 10, y: 10 }), + (this.pointerPosInput = this.pane.addInput(this, 'pointerPos', { label: 'pointer pos (world)' })), + this.pane.addInput(this, 'selectedEntityId', { label: 'Select By Id' }).on('change', (t) => this.selectEntityById(t.value)); + } + _buildEntityUI(e) { + var n, i; + this.selectedEntityFolder && + (this.selectedEntityFolder.dispose(), (this.selectedEntityFolder = this.selectedEntityTab.addFolder({ title: 'Selected' }))), + this.selectedEntityFolder.addBlade({ view: 'text', label: 'id', value: e.id.toString(), parse: (t) => String(t) }), + this.selectedEntityFolder.addInput(this.selectedEntity, 'name'), + this.selectedEntityFolder.addBlade({ + view: 'text', + label: 'tags', + value: e.tags.join(',') || 'none', + parse: (t) => String(t) + }), + e instanceof t.Actor && + e.color && + this.selectedEntityFolder.addInput(this.selectedEntity, 'color').on('change', (n) => { + e.color = new t.Color(n.value.r, n.value.g, n.value.b, n.value.a); + }), + this.selectedEntityFolder.addBlade({ + view: 'text', + label: 'parent', + value: e.parent + ? `(${null === (n = e.parent) || void 0 === n ? void 0 : n.id}) ${ + null === (i = e.parent) || void 0 === i ? void 0 : i.name + }` + : 'none', + parse: (t) => String(t) + }), + this.selectedEntityFolder.addBlade({ + view: 'list', + label: 'children', + options: e.children.map((t) => ({ text: `(${t.id}) ${t.name}`, value: t.id })), + value: e.children.length ? e.children[0].id : 'none' + }); + } + _buildColliderUI(e, n) { + var i, s; + if (e) { + const o = this.selectedEntityFolder.addFolder({ title: 'Collider & Body' }); + o.addBlade({ + view: 'text', + label: 'type', + value: null !== (s = null === (i = e.get()) || void 0 === i ? void 0 : i.constructor.name) && void 0 !== s ? s : 'none', + parse: (t) => String(t) + }), + n && + (o + .addBlade({ + view: 'list', + label: 'collisionType', + options: [ + t.CollisionType.Active, + t.CollisionType.Fixed, + t.CollisionType.Passive, + t.CollisionType.PreventCollision + ].map((t) => ({ text: t, value: t })), + value: n.collisionType + }) + .on('change', (t) => { + n.collisionType = t.value; + }), + o + .addBlade({ + view: 'list', + label: 'collisionGroup', + options: [t.CollisionGroup.All, ...t.CollisionGroupManager.groups].map((t) => ({ text: t.name, value: t })), + value: n.group + }) + .on('change', (t) => { + n.group = t.value; + })); + } + } + _buildParticleEmitterUI(t) { + const e = this.selectedEntityFolder.addFolder({ title: 'Particles' }); + e.addInput(t, 'isEmitting'), + e.addInput(t, 'emitRate'), + e.addInput(t, 'fadeFlag'), + e.addInput(t, 'particleLife', { min: 100, max: 1e4, step: 100 }), + e.addInput(t, 'width'), + e.addInput(t, 'height'), + e.addInput(t, 'minVel'), + e.addInput(t, 'maxVel'), + e.addInput(t, 'minAngle', { min: 0, max: 2 * Math.PI, step: 0.1 }), + e.addInput(t, 'maxAngle', { min: 0, max: 2 * Math.PI, step: 0.1 }), + e.addInput(t, 'minSize'), + e.addInput(t, 'maxSize'), + e.addInput(t, 'beginColor'), + e.addInput(t, 'endColor'), + e.addInput(t, 'opacity', { min: 0, max: 1, step: 0.01 }), + e.addInput(t, 'randomRotation'), + e.addInput(t, 'particleRotationalVelocity'); + } + _buildGraphicsUI(t) { + var e; + if (t) { + const n = this.selectedEntityFolder.addFolder({ title: 'Graphics' }); + n.addInput(t, 'anchor'), n.addInput(t, 'opacity', { min: 0, max: 1, step: 0.05 }), n.addInput(t, 'visible'); + const i = [], + s = [], + o = t.current.map((t) => t.graphic), + r = []; + let a = 0; + for (let e in t.graphics) i.push({ text: e, value: a++ }), s.push(t.graphics[e]), r.push(t.graphics[e]); + let l = 0; + for (let t of o) -1 === r.indexOf(t) && (i.push({ text: 'anonymous' + l++, value: a }), s.push(t)); + n.addBlade({ + view: 'list', + label: 'graphics', + options: i, + value: s.indexOf(null === (e = t.current[0]) || void 0 === e ? void 0 : e.graphic) + }).on('change', (e) => { + t.use(s[e.value]); + }); + } + } + _buildMotionUI(t) { + if (t) { + const e = this.selectedEntityFolder.addFolder({ title: 'Motion' }); + e.addInput(t, 'vel'), + e.addInput(t, 'acc'), + e.addInput(t, 'angularVelocity', { step: 0.1 }), + e.addInput(t, 'scaleFactor'), + e.addInput(t, 'inertia'); + } + } + _buildTransformUI(e) { + if (e) { + const n = this.selectedEntityFolder.addFolder({ title: 'Transform' }); + n.addBlade({ + view: 'list', + label: 'coord plane', + options: [t.CoordPlane.World, t.CoordPlane.Screen].map((t) => ({ text: t, value: t })), + value: e.coordPlane + }).on('change', (t) => (e.coordPlane = t.value)); + const i = n.addInput(e, 'pos'), + s = n.addInput(e, 'rotation', { min: 0, max: 2 * Math.PI }), + o = n.addInput(e, 'scale'); + n.addSeparator(); + const r = n.addInput(e, 'globalPos', { label: 'global pos' }), + a = n.addInput(e, 'globalRotation', { label: 'global rot', min: 0, max: 2 * Math.PI }), + l = n.addInput(e, 'globalScale', { label: 'global pos' }); + r.on('change', () => i.refresh()), + i.on('change', () => r.refresh()), + a.on('change', () => s.refresh()), + s.on('change', () => a.refresh()), + l.on('change', () => o.refresh()), + o.on('change', () => l.refresh()), + n.addInput(e, 'z', { label: 'z-index' }); + } + } + _buildScreenTab() { + (this.screenFolder = this.screenTab.addFolder({ title: 'Screen' })), + (this.currentResolution = this.engine.screen.resolution), + (this.currentViewport = this.engine.screen.viewport), + (this.resolutionText = this.screenFolder.addBlade({ + view: 'text', + label: 'resolution', + value: `(${this.engine.screen.resolution.width}x${this.engine.screen.resolution.height})`, + parse: (t) => String(t), + index: 0 + })), + (this.viewportText = this.screenFolder.addBlade({ + view: 'text', + label: 'viewport', + value: `(${this.engine.screen.viewport.width.toFixed(0)}x${this.engine.screen.viewport.height.toFixed(0)})`, + parse: (t) => String(t), + index: 1 + })), + this.screenFolder.addButton({ title: 'Fullscreen' }).on('click', () => { + this.engine.screen.goFullScreen(); + }); + } + _buildCameraTab() { + const t = this.cameraTab.addFolder({ title: 'Camera' }); + t.addInput(this.engine.currentScene.camera, 'zoom', { min: 0.01, max: 10, step: 0.5 }), + t.addInput(this.engine.currentScene.camera, 'pos'); + } + _buildClockTab() { + const e = this.clockTab.addFolder({ title: 'Clock' }); + let n = this.engine.clock instanceof t.TestClock, + i = 16; + const s = e.addButton({ title: 'step', disabled: !n, index: 2 }).on('click', () => this.engine.clock.step(i)); + e.addBlade({ view: 'slider', label: 'step (ms)', min: 1, max: 100, step: 16, value: i }).on('change', (t) => (i = t.value)), + e.addButton({ title: 'Use Test Clock', index: 0 }).on('click', () => { + this.engine.debug.useTestClock(), (n = !0), (s.disabled = !1); + }), + e.addButton({ title: 'Use Standard Clock', index: 1 }).on('click', () => { + this.engine.debug.useStandardClock(), (n = !1), (s.disabled = !0); + }), + this.pane.addSeparator(); + const o = e.addButton({ title: 'Stop', disabled: !1 }), + r = e.addButton({ title: 'Start', disabled: !0 }); + o.on('click', () => { + this.engine.clock.stop(), (r.disabled = !1), (o.disabled = !0); + }), + r.on('click', () => { + this.engine.clock.start(), (o.disabled = !1), (r.disabled = !0); + }); + } + _buildTimersTab() { + this.timerTab, + this._timersFolder && this._timersFolder.dispose(), + (this._timersFolder = this.timerTab.addFolder({ title: 'Timers' })); + for (let t of this.engine.currentScene.timers) { + let e = + t.repeats && -1 === t.maxNumberOfRepeats + ? 'repeats' + : t._numberOfTicks + 1 + ' of ' + (-1 === t.maxNumberOfRepeats ? 1 : t.maxNumberOfRepeats); + t.isRunning || (e = 'stopped'), + t.complete && (e = 'complete'), + this._timersFolder.addBlade({ + view: 'text', + label: `timer(${t.id})`, + value: `${e} next(${t.timeToNextAction.toFixed(0)}ms)`, + parse: (t) => String(t) + }); + } + } + _buildPhysicsTab() { + const e = this.physicsTab, + n = {}; + for (let e in t.Physics) n[e] = t.Physics[e]; + e.addInput(n, 'enabled').on('change', (e) => (t.Physics.enabled = e.value)), e.addInput(n, 'acc'); + const i = e.addInput(n, 'collisionResolutionStrategy'); + e.addButton({ title: 'Use Arcade' }).on('click', () => { + t.Physics.useArcadePhysics(), (n.collisionResolutionStrategy = t.Physics.collisionResolutionStrategy), i.refresh(); + }), + e.addButton({ title: 'Use Realistic' }).on('click', () => { + t.Physics.useRealisticPhysics(), (n.collisionResolutionStrategy = t.Physics.collisionResolutionStrategy), i.refresh(); + }), + e + .addInput(n, 'positionIterations', { min: 1, max: 30, step: 1 }) + .on('change', (e) => (t.Physics.positionIterations = e.value)), + e + .addInput(n, 'velocityIterations', { min: 1, max: 30, step: 1 }) + .on('change', (e) => (t.Physics.velocityIterations = e.value)), + e.addInput(n, 'checkForFastBodies').on('change', (e) => (t.Physics.checkForFastBodies = e.value)); + } + _buildDebugSettingsTab() { + const t = this.debugTab; + for (let e of ['entity', 'transform', 'motion', 'body', 'collider', 'physics', 'graphics', 'camera']) { + let n = t.addFolder({ title: e }); + if (this.engine.debug[e]) + for (let t in this.engine.debug[e]) + if (t) + if (t.toLocaleLowerCase().includes('color')) n.addInput(this.engine.debug[e], t); + else { + if (Array.isArray(this.engine.debug[e][t])) continue; + n.addInput(this.engine.debug[e], t); + } + } + } + } + })(), + s + ); + })(); +}); +//# sourceMappingURL=dev-tools.js.map diff --git a/sandbox/html/index.html b/sandbox/html/index.html index e8ed921e..98530e22 100644 --- a/sandbox/html/index.html +++ b/sandbox/html/index.html @@ -1,55 +1,54 @@ - + - + - - + +
-
stuff
- +
stuff
+
- - - \ No newline at end of file + + diff --git a/sandbox/index.html b/sandbox/index.html index af2e0dc0..7c953558 100644 --- a/sandbox/index.html +++ b/sandbox/index.html @@ -1,4 +1,4 @@ - + Excalibur Test Directory diff --git a/sandbox/src/game.ts b/sandbox/src/game.ts index e24dc3d7..357d131c 100644 --- a/sandbox/src/game.ts +++ b/sandbox/src/game.ts @@ -62,7 +62,7 @@ var game = new ex.Engine({ canvasImageRendering: 'auto', nativeContextAntialiasing: false, filtering: ex.ImageFiltering.Pixel, - multiSampleAntialiasing: true, + multiSampleAntialiasing: true }, uvPadding: 0, physics: { @@ -102,9 +102,9 @@ game.currentScene.onPreDraw = (ctx: ex.ExcaliburGraphicsContext) => { const yellow = ex.Color.fromHex('#FDCF45'); const bb = game.screen.contentArea.clone(); - bb.top++ - bb.left++ - bb.bottom-- + bb.top++; + bb.left++; + bb.bottom--; bb.right--; bb.draw(ctx, ex.Color.Yellow); @@ -113,7 +113,7 @@ game.currentScene.onPreDraw = (ctx: ex.ExcaliburGraphicsContext) => { ctx.drawCircle(ex.vec(bb.left + 6, bb.bottom - 6), 10, yellow); ctx.drawCircle(ex.vec(bb.right - 6, bb.bottom - 6), 10, red); ctx.restore(); -} +}; game.on('fallbackgraphicscontext', (ctx) => { console.log('fallback triggered', ctx); @@ -121,7 +121,6 @@ game.on('fallbackgraphicscontext', (ctx) => { //@ts-ignore For some reason ts doesn't like the /// slash import // const devtool = new ex.DevTools.DevTool(game); - // var colorblind = new ex.ColorBlindnessPostProcessor(ex.ColorBlindnessMode.Deuteranope); // game.graphicsContext.addPostProcessor(colorblind); @@ -134,7 +133,6 @@ fullscreenButton.addEventListener('click', () => { }); game.showDebug(true); - var heartTex = new ex.ImageSource('../images/heart.png'); var heartImageSource = new ex.ImageSource('../images/heart.png'); var imageRun = new ex.ImageSource('../images/PlayerRun.png', false, ex.ImageFiltering.Blended); @@ -171,8 +169,6 @@ boot.addResource(jump); // Set background color game.backgroundColor = new ex.Color(114, 213, 224); - - // Add some UI //var heart = new ex.ScreenElement(0, 0, 20, 20); var heart = new ex.ScreenElement({ x: 0, y: 0, width: 20 * 2, height: 20 * 2 }); @@ -238,23 +234,21 @@ var cardSpriteSheet = ex.SpriteSheet.fromImageSource({ }, spacing: { originOffset: { x: 11, y: 2 }, - margin: { x: 23, y: 5} + margin: { x: 23, y: 5 } } }); -cardSpriteSheet.sprites.forEach(s => s.scale = ex.vec(2, 2)); +cardSpriteSheet.sprites.forEach((s) => (s.scale = ex.vec(2, 2))); var cardAnimation = ex.Animation.fromSpriteSheet(cardSpriteSheet, ex.range(0, 14 * 4), 200); var multiCardSheet = ex.SpriteSheet.fromImageSourceWithSourceViews({ image: cards, - sourceViews: [ - { x: 11, y: 2, width: 42*2 + 23, height: 60*2 + 5 } - ] + sourceViews: [{ x: 11, y: 2, width: 42 * 2 + 23, height: 60 * 2 + 5 }] }); var multiCardActor = new ex.Actor({ - pos: ex.vec(400, 100), + pos: ex.vec(400, 100) }); multiCardActor.graphics.use(multiCardSheet.sprites[0]); @@ -269,7 +263,7 @@ for (var i = 0; i < 100; i++) { z: -10 }); clouds.graphics.use(cloudSprite); - var parallax = new ex.ParallaxComponent(ex.vec(rand.floating(.5, .9), .5)); + var parallax = new ex.ParallaxComponent(ex.vec(rand.floating(0.5, 0.9), 0.5)); clouds.addComponent(parallax); clouds.vel.x = -10; @@ -366,13 +360,12 @@ heart.graphics.add(group); heart.pos = ex.vec(10, 10); game.add(heart); -var label = new ex.Label({text: 'Test Label', x: 200, y: 200}); +var label = new ex.Label({ text: 'Test Label', x: 200, y: 200 }); game.add(label); -var testSpriteLabel = new ex.Label({text: 'Test Sprite Label', x: 200, y: 100, spriteFont: spriteFont}); +var testSpriteLabel = new ex.Label({ text: 'Test Sprite Label', x: 200, y: 100, spriteFont: spriteFont }); game.add(testSpriteLabel); - var pointer = new ex.Actor({ width: 25, height: 25, @@ -385,7 +378,7 @@ var otherPointer = new ex.ScreenElement({ color: ex.Color.Blue }); var pagePointer = document.getElementById('page') as HTMLDivElement; -otherPointer.anchor.setTo(.5, .5); +otherPointer.anchor.setTo(0.5, 0.5); game.add(otherPointer); // game.input.pointers.primary.on('move', (ev) => { // pointer.pos = ev.worldPos; @@ -397,9 +390,9 @@ game.add(otherPointer); game.input.pointers.primary.on('wheel', (ev) => { pointer.pos.setTo(ev.x, ev.y); - game.currentScene.camera.zoom += (ev.deltaY / 1000); - game.currentScene.camera.zoom = ex.clamp(game.currentScene.camera.zoom, .05, 100); -}) + game.currentScene.camera.zoom += ev.deltaY / 1000; + game.currentScene.camera.zoom = ex.clamp(game.currentScene.camera.zoom, 0.05, 100); +}); // Turn on debug diagnostics game.showDebug(false); var blockSprite = new ex.Sprite({ @@ -435,18 +428,18 @@ var spriteSheetJump = ex.SpriteSheet.fromImageSource({ }); var tileBlockWidth = 64, tileBlockHeight = 48, - spriteTiles = new ex.SpriteSheet({sprites: [ex.Sprite.from(imageBlocks)] }); + spriteTiles = new ex.SpriteSheet({ sprites: [ex.Sprite.from(imageBlocks)] }); var blockGroup = ex.CollisionGroupManager.create('ground'); // create a collision map // var tileMap = new ex.TileMap(100, 300, tileBlockWidth, tileBlockHeight, 4, 500); var tileMap = new ex.TileMap({ - name: 'tilemap', + name: 'tilemap', pos: ex.vec(-300, 300), tileWidth: tileBlockWidth, tileHeight: tileBlockHeight, rows: 4, - columns: 500 + columns: 500 }); tileMap.get(ex.BodyComponent).group = blockGroup; // tileMap.get(ex.TransformComponent).coordPlane = ex.CoordPlane.Screen; @@ -459,7 +452,7 @@ var blocks = ex.Sprite.from(imageBlocks); // { graphic: flipped, duration: 200 } // ] // }) -tileMap.tiles.forEach(function(cell: ex.Tile) { +tileMap.tiles.forEach(function (cell: ex.Tile) { cell.solid = true; cell.addGraphic(spriteTiles.sprites[0]); }); @@ -526,35 +519,37 @@ for (var i = 0; i < 36; i++) { game.add(block); } -var platform = new ex.Actor({x: 400, y: 300, width: 200, height: 50, color: new ex.Color(0, 200, 0)}); +var platform = new ex.Actor({ x: 400, y: 300, width: 200, height: 50, color: new ex.Color(0, 200, 0) }); platform.graphics.add(new ex.Rectangle({ color: new ex.Color(0, 200, 0), width: 200, height: 50 })); platform.body.collisionType = ex.CollisionType.Fixed; platform.body.group = blockGroup; -platform.actions.repeatForever(ctx => ctx.moveTo(200, 300, 100).moveTo(600, 300, 100).moveTo(400, 300, 100)); +platform.actions.repeatForever((ctx) => ctx.moveTo(200, 300, 100).moveTo(600, 300, 100).moveTo(400, 300, 100)); game.add(platform); -var platform2 = new ex.Actor({x: 800, y: 300, width: 200, height: 20, color: new ex.Color(0, 0, 140)}); +var platform2 = new ex.Actor({ x: 800, y: 300, width: 200, height: 20, color: new ex.Color(0, 0, 140) }); platform2.graphics.add(new ex.Rectangle({ color: new ex.Color(0, 0, 140), width: 200, height: 20 })); platform2.body.collisionType = ex.CollisionType.Fixed; platform2.body.group = blockGroup; -platform2.actions.repeatForever(ctx => ctx.moveTo(2000, 300, 100).moveTo(2000, 100, 100).moveTo(800, 100, 100).moveTo(800, 300, 100)); +platform2.actions.repeatForever((ctx) => ctx.moveTo(2000, 300, 100).moveTo(2000, 100, 100).moveTo(800, 100, 100).moveTo(800, 300, 100)); game.add(platform2); -var platform3 = new ex.Actor({x: -200, y: 400, width: 200, height: 20, color: new ex.Color(50, 0, 100)}); +var platform3 = new ex.Actor({ x: -200, y: 400, width: 200, height: 20, color: new ex.Color(50, 0, 100) }); platform3.graphics.add(new ex.Rectangle({ color: new ex.Color(50, 0, 100), width: 200, height: 20 })); platform3.body.collisionType = ex.CollisionType.Fixed; platform3.body.group = blockGroup; -platform3.actions.repeatForever(ctx => ctx.moveTo(-200, 800, 300).moveTo(-200, 400, 50).delay(3000).moveTo(-200, 300, 800).moveTo(-200, 400, 800)); +platform3.actions.repeatForever((ctx) => + ctx.moveTo(-200, 800, 300).moveTo(-200, 400, 50).delay(3000).moveTo(-200, 300, 800).moveTo(-200, 400, 800) +); game.add(platform3); -var platform4 = new ex.Actor({x: 75, y: 300, width: 100, height: 50, color: ex.Color.Azure}); +var platform4 = new ex.Actor({ x: 75, y: 300, width: 100, height: 50, color: ex.Color.Azure }); platform4.graphics.add(new ex.Rectangle({ color: ex.Color.Azure, width: 100, height: 50 })); platform4.body.collisionType = ex.CollisionType.Fixed; platform4.body.group = blockGroup; game.add(platform4); // Test follow api -var follower = new ex.Actor({x: 50, y: 100, width: 20, height: 20, color: ex.Color.Black}); +var follower = new ex.Actor({ x: 50, y: 100, width: 20, height: 20, color: ex.Color.Black }); follower.graphics.add(new ex.Rectangle({ color: ex.Color.Black, width: 20, height: 20 })); follower.body.collisionType = ex.CollisionType.PreventCollision; game.add(follower); @@ -573,7 +568,7 @@ player.onPostUpdate = (engine) => { searchAllColliders: false }); // console.log(hits); -} +}; // player.graphics.onPostDraw = (ctx) => { // ctx.drawLine(ex.Vector.Zero, ex.Vector.Down.scale(100), ex.Color.Red, 2); // } @@ -586,12 +581,12 @@ follower.actions console.log('Player met!!'); }); -player.onCollisionStart = (_a,_b,_c, contact) => { +player.onCollisionStart = (_a, _b, _c, contact) => { console.log('start', contact); -} -player.onCollisionEnd = (_a,_b) => { +}; +player.onCollisionEnd = (_a, _b) => { console.log('end'); -} +}; // follow player @@ -611,14 +606,13 @@ var healthbar = new ex.Actor({ y: -70, width: 140, height: 5, - color: new ex.Color(0, 255, 0)}); + color: new ex.Color(0, 255, 0) +}); player.addChild(healthbar); player.onPostUpdate = () => { - ex.Debug.drawLine( - player.pos, - player.pos.add(ex.Vector.Down.scale(100)), { - color: ex.Color.Red - }); + ex.Debug.drawLine(player.pos, player.pos.add(ex.Vector.Down.scale(100)), { + color: ex.Color.Red + }); ex.Debug.drawPoint(player.pos, { size: 1, color: ex.Color.Violet @@ -629,7 +623,7 @@ player.onPostUpdate = () => { width: 1 }); ex.Debug.drawBounds(player.collider.bounds, { color: ex.Color.Yellow }); -} +}; // player.onPostDraw = (ctx: CanvasRenderingContext2D) => { // ctx.fillStyle = 'red'; // ctx.fillRect(0, 0, 100, 100); @@ -644,10 +638,10 @@ class OtherActor extends ex.Actor { super(args); } onCollisionStart(self: ex.Collider, other: ex.Collider, side: ex.Side, contact: ex.CollisionContact): void { - console.log('other collision start') + console.log('other collision start'); } onCollisionEnd(self: ex.Collider, other: ex.Collider): void { - console.log('other collision end') + console.log('other collision end'); } } @@ -678,10 +672,10 @@ var playerText = new ex.Text({ var group = new ex.GraphicsGroup({ members: [ - { graphic: healthbar2, offset: ex.vec(0, -70)}, - { graphic: playerText, offset: ex.vec(0, -70)} + { graphic: healthbar2, offset: ex.vec(0, -70) }, + { graphic: playerText, offset: ex.vec(0, -70) } ] -}) +}); healthbar.graphics.use(group); // var backgroundLayer = player.graphics.layers.create({ @@ -701,12 +695,7 @@ var right = left.clone(); // spriteSheetRun.getAnimationBetween(game, 1, 11, 50) right.flipHorizontal = true; var idle = ex.Animation.fromSpriteSheet(spriteSheetRun, [0], 200); // spriteSheetRun.getAnimationByIndices(game, [0], 200); //idle.anchor.setTo(.5, .5); -var jumpLeft = ex.Animation.fromSpriteSheet( - spriteSheetJump, - ex.range(0, 10).reverse(), - 100, - ex.AnimationStrategy.Freeze -); // spriteSheetJump.getAnimationBetween(game, 0, 11, 100); +var jumpLeft = ex.Animation.fromSpriteSheet(spriteSheetJump, ex.range(0, 10).reverse(), 100, ex.AnimationStrategy.Freeze); // spriteSheetJump.getAnimationBetween(game, 0, 11, 100); var jumpRight = ex.Animation.fromSpriteSheet(spriteSheetJump, ex.range(11, 21), 100, ex.AnimationStrategy.Freeze); // spriteSheetJump.getAnimationBetween(game, 11, 22, 100); // left.loop = true; // right.loop = true; @@ -799,7 +788,7 @@ player.on('pointerwheel', () => { var newScene = new ex.Scene(); newScene.backgroundColor = ex.Color.Yellow; -newScene.add(new ex.Label({text: 'MAH LABEL!', x: 200, y: 100})); +newScene.add(new ex.Label({ text: 'MAH LABEL!', x: 200, y: 100 })); newScene.on('activate', (evt?: ex.ActivateEvent) => { console.log('activate newScene'); }); @@ -813,7 +802,7 @@ game.addScene('label', newScene); game.input.keyboard.on('down', (keyDown?: ex.KeyEvent) => { if (keyDown.key === ex.Keys.F) { - var a = new ex.Actor({x: player.pos.x + 10, y: player.pos.y - 50, width: 10, height: 10, color: new ex.Color(222, 222, 222)}); + var a = new ex.Actor({ x: player.pos.x + 10, y: player.pos.y - 50, width: 10, height: 10, color: new ex.Color(222, 222, 222) }); a.vel.x = 200 * direction; a.vel.y = 0; a.body.collisionType = ex.CollisionType.Active; @@ -896,7 +885,7 @@ player.on('initialize', (evt?: ex.InitializeEvent) => { game.input.keyboard.on('down', (keyDown?: ex.KeyEvent) => { if (keyDown.key === ex.Keys.B) { - var block = new ex.Actor({x: currentX, y: 350, width: 44, height: 50, color: color}); + var block = new ex.Actor({ x: currentX, y: 350, width: 44, height: 50, color: color }); currentX += 46; block.graphics.add(blockAnimation); game.add(block); @@ -951,7 +940,7 @@ const original = (ex.ParticleEmitter.prototype as any)._createParticle; const particle = original.call(this); particle.graphics.onPostDraw = () => {}; return particle; -} +}; game.add(emitter); var exploding = false; @@ -1014,4 +1003,4 @@ game.currentScene.camera.y = 200; // Run the mainloop game.start(boot).then(() => { logger.info('All Resources have finished loading'); -}); \ No newline at end of file +}); diff --git a/sandbox/stats/stats.js b/sandbox/stats/stats.js index 2f1a0e13..525239ef 100644 --- a/sandbox/stats/stats.js +++ b/sandbox/stats/stats.js @@ -1,5 +1,108 @@ // stats.js - http://github.com/mrdoob/stats.js -(function(f,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"===typeof define&&define.amd?define(e):f.Stats=e()})(this,function(){var f=function(){function e(a){c.appendChild(a.dom);return a}function u(a){for(var d=0;d=g+1E3&&(r.update(1E3*a/(c-g),100),g=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/ - 1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){k=this.end()},domElement:c,setMode:u}};f.Panel=function(e,f,l){var c=Infinity,k=0,g=Math.round,a=g(window.devicePixelRatio||1),r=80*a,h=48*a,t=3*a,v=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=h;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,h);b.fillStyle=f;b.fillText(e,t,v); - b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(h,w){c=Math.min(c,h);k=Math.max(k,h);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=f;b.fillText(g(h)+" "+e+" ("+g(c)+"-"+g(k)+")",t,v);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,g((1-h/w)*p))}}};return f}); \ No newline at end of file +(function (f, e) { + 'object' === typeof exports && 'undefined' !== typeof module + ? (module.exports = e()) + : 'function' === typeof define && define.amd + ? define(e) + : (f.Stats = e()); +})(this, function () { + var f = function () { + function e(a) { + c.appendChild(a.dom); + return a; + } + function u(a) { + for (var d = 0; d < c.children.length; d++) c.children[d].style.display = d === a ? 'block' : 'none'; + l = a; + } + var l = 0, + c = document.createElement('div'); + c.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000'; + c.addEventListener( + 'click', + function (a) { + a.preventDefault(); + u(++l % c.children.length); + }, + !1 + ); + var k = (performance || Date).now(), + g = k, + a = 0, + r = e(new f.Panel('FPS', '#0ff', '#002')), + h = e(new f.Panel('MS', '#0f0', '#020')); + if (self.performance && self.performance.memory) var t = e(new f.Panel('MB', '#f08', '#201')); + u(0); + return { + REVISION: 16, + dom: c, + addPanel: e, + showPanel: u, + begin: function () { + k = (performance || Date).now(); + }, + end: function () { + a++; + var c = (performance || Date).now(); + h.update(c - k, 200); + if (c >= g + 1e3 && (r.update((1e3 * a) / (c - g), 100), (g = c), (a = 0), t)) { + var d = performance.memory; + t.update(d.usedJSHeapSize / 1048576, d.jsHeapSizeLimit / 1048576); + } + return c; + }, + update: function () { + k = this.end(); + }, + domElement: c, + setMode: u + }; + }; + f.Panel = function (e, f, l) { + var c = Infinity, + k = 0, + g = Math.round, + a = g(window.devicePixelRatio || 1), + r = 80 * a, + h = 48 * a, + t = 3 * a, + v = 2 * a, + d = 3 * a, + m = 15 * a, + n = 74 * a, + p = 30 * a, + q = document.createElement('canvas'); + q.width = r; + q.height = h; + q.style.cssText = 'width:80px;height:48px'; + var b = q.getContext('2d'); + b.font = 'bold ' + 9 * a + 'px Helvetica,Arial,sans-serif'; + b.textBaseline = 'top'; + b.fillStyle = l; + b.fillRect(0, 0, r, h); + b.fillStyle = f; + b.fillText(e, t, v); + b.fillRect(d, m, n, p); + b.fillStyle = l; + b.globalAlpha = 0.9; + b.fillRect(d, m, n, p); + return { + dom: q, + update: function (h, w) { + c = Math.min(c, h); + k = Math.max(k, h); + b.fillStyle = l; + b.globalAlpha = 1; + b.fillRect(0, 0, r, m); + b.fillStyle = f; + b.fillText(g(h) + ' ' + e + ' (' + g(c) + '-' + g(k) + ')', t, v); + b.drawImage(q, d + a, m, n - a, p, d, m, n - a, p); + b.fillRect(d + n - a, m, a, p); + b.fillStyle = l; + b.globalAlpha = 0.9; + b.fillRect(d + n - a, m, a, g((1 - h / w) * p)); + } + }; + }; + return f; +}); diff --git a/sandbox/tests/animation-events/index.html b/sandbox/tests/animation-events/index.html index 9da75190..f64702c6 100644 --- a/sandbox/tests/animation-events/index.html +++ b/sandbox/tests/animation-events/index.html @@ -1,18 +1,18 @@ - + - - - - Animation Events - - - Should see all the different animation events in the console. -
    -
  • Frame for each frame
  • -
  • End after the first end, then it is reset to loop
  • -
  • Loop every animation afterwards
  • -
- - - - \ No newline at end of file + + + + Animation Events + + + Should see all the different animation events in the console. +
    +
  • Frame for each frame
  • +
  • End after the first end, then it is reset to loop
  • +
  • Loop every animation afterwards
  • +
+ + + + diff --git a/sandbox/tests/animation-events/index.ts b/sandbox/tests/animation-events/index.ts index f63d7da9..475c453e 100644 --- a/sandbox/tests/animation-events/index.ts +++ b/sandbox/tests/animation-events/index.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 400, height: 400 @@ -9,24 +8,24 @@ var animationImage = new ex.ImageSource('./explosion.png'); var explosionSpriteSheet = ex.SpriteSheet.fromImageSource({ image: animationImage, grid: { - rows: 2, - columns: 5, - spriteHeight: 32, - spriteWidth: 32 + rows: 2, + columns: 5, + spriteHeight: 32, + spriteWidth: 32 } }); var animation = ex.Animation.fromSpriteSheetCoordinates({ spriteSheet: explosionSpriteSheet, frameCoordinates: [ - {x: 0, y: 0, duration: 100 }, - {x: 1, y: 0, duration: 100 }, - {x: 2, y: 0, duration: 100 }, - {x: 3, y: 0, duration: 100 }, - {x: 4, y: 0, duration: 100 }, - {x: 0, y: 1, duration: 100 }, - {x: 1, y: 1, duration: 100 }, - {x: 2, y: 1, duration: 100 }, + { x: 0, y: 0, duration: 100 }, + { x: 1, y: 0, duration: 100 }, + { x: 2, y: 0, duration: 100 }, + { x: 3, y: 0, duration: 100 }, + { x: 4, y: 0, duration: 100 }, + { x: 0, y: 1, duration: 100 }, + { x: 1, y: 1, duration: 100 }, + { x: 2, y: 1, duration: 100 } ], strategy: ex.AnimationStrategy.End }); @@ -34,24 +33,23 @@ var animation = ex.Animation.fromSpriteSheetCoordinates({ animation.scale = ex.vec(10, 10); animation.events.on('frame', (evt) => { - console.log('frame', evt) + console.log('frame', evt); }); animation.events.on('end', (anim) => { - console.log('end', anim) + console.log('end', anim); anim.strategy = ex.AnimationStrategy.Loop; anim.reset(); }); animation.events.on('loop', (anim) => { - console.log('loop', anim) + console.log('loop', anim); }); var loader = new ex.Loader([animationImage]); var actor = new ex.Actor({ - pos: ex.vec(200, 200), + pos: ex.vec(200, 200) }); actor.graphics.use(animation); game.add(actor); game.start(loader); - diff --git a/sandbox/tests/arcadecollider/index.html b/sandbox/tests/arcadecollider/index.html index 7e269f80..6feea88e 100644 --- a/sandbox/tests/arcadecollider/index.html +++ b/sandbox/tests/arcadecollider/index.html @@ -1,13 +1,13 @@ - + - - - - - Arcade Collision Solver - - - - - - \ No newline at end of file + + + + + Arcade Collision Solver + + + + + + diff --git a/sandbox/tests/arcadecollider/index.ts b/sandbox/tests/arcadecollider/index.ts index f6367cbb..19e9a999 100644 --- a/sandbox/tests/arcadecollider/index.ts +++ b/sandbox/tests/arcadecollider/index.ts @@ -1,4 +1,3 @@ - // 0,0 3.0625,0 3,6.0625 -0.0625,6 var game = new ex.Engine({ @@ -19,21 +18,20 @@ player.onPostUpdate = () => { player.vel.setTo(0, 0); const speed = 64; if (game.input.keyboard.isHeld(ex.Keys.Right)) { - player.vel.x = speed; + player.vel.x = speed; } if (game.input.keyboard.isHeld(ex.Keys.Left)) { - player.vel.x = -speed; + player.vel.x = -speed; } if (game.input.keyboard.isHeld(ex.Keys.Up)) { - player.vel.y = -speed; + player.vel.y = -speed; } if (game.input.keyboard.isHeld(ex.Keys.Down)) { - player.vel.y = speed; + player.vel.y = speed; } -} +}; game.add(player); - // {_x: 6.0625, _y: 8.875} // {_x: 9.125, _y: 8.875} // {_x: 9.0625, _y: 14.9375} @@ -44,7 +42,7 @@ game.add(player); // {_x: 361.0625, _y: 174.9375} // {_x: 358, _y: 174.875} -// offset +// offset // _x: 352 // _y: 160 var offset = ex.vec(352, 160); @@ -54,21 +52,15 @@ var collider = new ex.Actor({ pos: ex.vec(150, 100), collisionType: ex.CollisionType.Fixed }); -var points = [ - ex.vec(6.0625, 8.875), - ex.vec(9.125, 8.875), - ex.vec(9.0625, 14.9375), - ex.vec(6, 14.875) -]; -collider.graphics.use(new ex.Polygon({points, color: ex.Color.Red}), { offset }); +var points = [ex.vec(6.0625, 8.875), ex.vec(9.125, 8.875), ex.vec(9.0625, 14.9375), ex.vec(6, 14.875)]; +collider.graphics.use(new ex.Polygon({ points, color: ex.Color.Red }), { offset }); const polygon = ex.Shape.Polygon(points); polygon.offset = offset; var composite = collider.collider.useCompositeCollider([polygon]); // collider.collider.set(polygon); game.add(collider); - -game.currentScene.camera.strategy.elasticToActor(player, .8, .9); +game.currentScene.camera.strategy.elasticToActor(player, 0.8, 0.9); game.currentScene.camera.zoom = 2; -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/arcadeseam/index.html b/sandbox/tests/arcadeseam/index.html index 64f645f4..2d8aaafe 100644 --- a/sandbox/tests/arcadeseam/index.html +++ b/sandbox/tests/arcadeseam/index.html @@ -1,14 +1,14 @@ - + - - - - - Arcade Collision Solver - Seam - - -

Compare with physics.arcade.contactSolveBias: None & physics.arcade.contactSolveBias: VerticalFirst

- - - - \ No newline at end of file + + + + + Arcade Collision Solver - Seam + + +

Compare with physics.arcade.contactSolveBias: None & physics.arcade.contactSolveBias: VerticalFirst

+ + + + diff --git a/sandbox/tests/arcadeseam/index.ts b/sandbox/tests/arcadeseam/index.ts index 11ae19bd..8904d560 100644 --- a/sandbox/tests/arcadeseam/index.ts +++ b/sandbox/tests/arcadeseam/index.ts @@ -19,7 +19,7 @@ game.toggleDebug(); var lastWidth = 200; var lastPos = ex.vec(0, 0); for (let x = 0; x < 10; x++) { - const width = (x % 2 === 1 ? 16 : 200); + const width = x % 2 === 1 ? 16 : 200; game.add( new ex.Actor({ name: 'floor-tile', @@ -46,22 +46,21 @@ var player = new ex.Actor({ player.onPostUpdate = () => { const speed = 164; if (game.input.keyboard.isHeld(ex.Keys.Right)) { - player.vel.x = speed; + player.vel.x = speed; } if (game.input.keyboard.isHeld(ex.Keys.Left)) { - player.vel.x = -speed; + player.vel.x = -speed; } if (game.input.keyboard.isHeld(ex.Keys.Up)) { - player.vel.y = -speed; + player.vel.y = -speed; } if (game.input.keyboard.isHeld(ex.Keys.Down)) { - player.vel.y = speed; + player.vel.y = speed; } -} +}; game.add(player); - -game.currentScene.camera.strategy.elasticToActor(player, .8, .9); +game.currentScene.camera.strategy.elasticToActor(player, 0.8, 0.9); game.currentScene.camera.zoom = 2; -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/boundingbox/bbtester.html b/sandbox/tests/boundingbox/bbtester.html index ef3b0ccc..2a242f02 100644 --- a/sandbox/tests/boundingbox/bbtester.html +++ b/sandbox/tests/boundingbox/bbtester.html @@ -1,17 +1,17 @@ - + - - - - + + + + BB Tester - - + +

Click to drag the red square

The vector on screen should show the direction that the blue square needs to go to move out of the way of the red.

Vector is shown in the console

- - \ No newline at end of file + + diff --git a/sandbox/tests/camera-animation/index.html b/sandbox/tests/camera-animation/index.html index 15f2626a..8c63ca36 100644 --- a/sandbox/tests/camera-animation/index.html +++ b/sandbox/tests/camera-animation/index.html @@ -1,11 +1,9 @@ - + - - - - Camera Animation - - - - - \ No newline at end of file + + + + Camera Animation + + + diff --git a/sandbox/tests/camera/lerp.html b/sandbox/tests/camera/lerp.html index 361c277c..a90cb278 100644 --- a/sandbox/tests/camera/lerp.html +++ b/sandbox/tests/camera/lerp.html @@ -1,15 +1,20 @@ - + - + Camera Lerp Test - - - + +
@@ -26,8 +31,7 @@

Easing: TRUE FALSE

- - + diff --git a/sandbox/tests/camera/lerp.ts b/sandbox/tests/camera/lerp.ts index 279042d0..bfa80a8b 100644 --- a/sandbox/tests/camera/lerp.ts +++ b/sandbox/tests/camera/lerp.ts @@ -5,7 +5,7 @@ var game = new ex.Engine({ height: 400, pointerScope: ex.PointerScope.Canvas }); -var actor = new ex.Actor({x: 100, y: 100, width: 50, height: 50, color: ex.Color.Red}); +var actor = new ex.Actor({ x: 100, y: 100, width: 50, height: 50, color: ex.Color.Red }); game.add(actor); diff --git a/sandbox/tests/camera/strategy.html b/sandbox/tests/camera/strategy.html index 193d24c1..423dddf5 100644 --- a/sandbox/tests/camera/strategy.html +++ b/sandbox/tests/camera/strategy.html @@ -1,15 +1,20 @@ - + - + Camera Strategy Test - - - + +
@@ -18,8 +23,7 @@
- - + diff --git a/sandbox/tests/camera/strategy.ts b/sandbox/tests/camera/strategy.ts index 529e056a..34718cd9 100644 --- a/sandbox/tests/camera/strategy.ts +++ b/sandbox/tests/camera/strategy.ts @@ -5,14 +5,14 @@ var game = new ex.Engine({ height: 400, pointerScope: ex.PointerScope.Canvas }); -var actor = new ex.Actor({x: 100, y: 100, width: 50, height: 50, color: ex.Color.Red}); +var actor = new ex.Actor({ x: 100, y: 100, width: 50, height: 50, color: ex.Color.Red }); -actor.actions.repeatForever(ctx => ctx.moveTo(300, 300, 100).moveTo(100, 100, 100)); +actor.actions.repeatForever((ctx) => ctx.moveTo(300, 300, 100).moveTo(100, 100, 100)); game.add(actor); -var actor2 = new ex.Actor({x: 80, y: 80, width: 10, height: 10, color: ex.Color.Black}); -var actor3 = new ex.Actor({x: 320, y: 320, width: 10, height: 10, color: ex.Color.Black}); +var actor2 = new ex.Actor({ x: 80, y: 80, width: 10, height: 10, color: ex.Color.Black }); +var actor3 = new ex.Actor({ x: 320, y: 320, width: 10, height: 10, color: ex.Color.Black }); game.add(actor2); game.add(actor3); diff --git a/sandbox/tests/camera/zoom.html b/sandbox/tests/camera/zoom.html index edc0b63a..49a62542 100644 --- a/sandbox/tests/camera/zoom.html +++ b/sandbox/tests/camera/zoom.html @@ -1,12 +1,12 @@ - + - - Camera Zooom - - - - - -

Click to zoom in and out over time

- - \ No newline at end of file + + Camera Zooom + + + + + +

Click to zoom in and out over time

+ + diff --git a/sandbox/tests/clonebehavior/index.html b/sandbox/tests/clonebehavior/index.html index 92599985..c3ab7789 100644 --- a/sandbox/tests/clonebehavior/index.html +++ b/sandbox/tests/clonebehavior/index.html @@ -1,14 +1,14 @@ - + - - - - - Clone Behavior - - -

The clones should be 2 separate colors and no collision handler should fire in the console.

- - - - \ No newline at end of file + + + + + Clone Behavior + + +

The clones should be 2 separate colors and no collision handler should fire in the console.

+ + + + diff --git a/sandbox/tests/clonebehavior/index.ts b/sandbox/tests/clonebehavior/index.ts index 3248387f..9ad8f460 100644 --- a/sandbox/tests/clonebehavior/index.ts +++ b/sandbox/tests/clonebehavior/index.ts @@ -1,15 +1,17 @@ var game = new ex.Engine({ width: 800, - height: 600, + height: 600 }); game.start(); var paddle = new ex.Actor({ - x: 150, y: 40, - width: 200, height: 20, + x: 150, + y: 40, + width: 200, + height: 20, color: ex.Color.Chartreuse, - collisionType: ex.CollisionType.Active, + collisionType: ex.CollisionType.Active }); game.add(paddle); @@ -17,16 +19,20 @@ var paddle2 = paddle.clone(); paddle2.pos.x = 400; paddle2.color = ex.Color.Red; -paddle2.on('collisionstart', (ev)=>{console.log(ev);}); +paddle2.on('collisionstart', (ev) => { + console.log(ev); +}); game.add(paddle2); ex.Physics.useRealisticPhysics(); -ex.Physics.gravity = ex.vec(0,60); +ex.Physics.gravity = ex.vec(0, 60); const wall = new ex.Actor({ - x: 100, y: 400, - width: 200, height: 20, + x: 100, + y: 400, + width: 200, + height: 20, color: ex.Color.Black, collisionType: ex.CollisionType.Fixed }); -game.add(wall); \ No newline at end of file +game.add(wall); diff --git a/sandbox/tests/collision/index.html b/sandbox/tests/collision/index.html index 441ef549..fc750019 100644 --- a/sandbox/tests/collision/index.html +++ b/sandbox/tests/collision/index.html @@ -1,10 +1,10 @@ - + - + - - + + - + diff --git a/sandbox/tests/collision/index.ts b/sandbox/tests/collision/index.ts index f01d5a07..18b4bd60 100644 --- a/sandbox/tests/collision/index.ts +++ b/sandbox/tests/collision/index.ts @@ -2,7 +2,7 @@ var engine = new ex.Engine({ width: 600, height: 400 }); -var active = new ex.Actor({x: 0, y: -50, width: 100, height: 100, color: ex.Color.Cyan}); +var active = new ex.Actor({ x: 0, y: -50, width: 100, height: 100, color: ex.Color.Cyan }); active.body.collisionType = ex.CollisionType.Active; active.vel.y = 100; active.acc.y = 900; @@ -10,12 +10,11 @@ active.on('postupdate', () => { //console.log('current dy', active.dy); }); -var fixed = new ex.Actor({x: 0, y: 50, width: 100, height: 100, color: ex.Color.Green}); +var fixed = new ex.Actor({ x: 0, y: 50, width: 100, height: 100, color: ex.Color.Green }); fixed.body.collisionType = ex.CollisionType.Fixed; -fixed.actions.repeatForever(ctx => { - ctx.moveTo(0, 100, 300) - .moveTo(0, 50, 300) +fixed.actions.repeatForever((ctx) => { + ctx.moveTo(0, 100, 300).moveTo(0, 50, 300); }); engine.add(active); diff --git a/sandbox/tests/collision/passive.html b/sandbox/tests/collision/passive.html index cac76786..f2338c14 100644 --- a/sandbox/tests/collision/passive.html +++ b/sandbox/tests/collision/passive.html @@ -1,14 +1,13 @@ - + - - - Passive check - - + + Passive check + +
Blocks should pass through eachother without bouncing
Collision events should be visible in console
Post Collision events should be NOT visible in console
- + diff --git a/sandbox/tests/collision/passive.ts b/sandbox/tests/collision/passive.ts index bf6932e9..7986cab9 100644 --- a/sandbox/tests/collision/passive.ts +++ b/sandbox/tests/collision/passive.ts @@ -6,7 +6,7 @@ var game = new ex.Engine({ ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Arcade; -var activeBlock = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); +var activeBlock = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; activeBlock.vel.x = 100; game.add(activeBlock); @@ -19,7 +19,7 @@ activeBlock.on('postcollision', () => { console.error('Active block should not fire post collision'); }); -var passiveBlock = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); +var passiveBlock = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); passiveBlock.body.collisionType = ex.CollisionType.Passive; passiveBlock.vel.x = -100; game.add(passiveBlock); diff --git a/sandbox/tests/collision/touching.html b/sandbox/tests/collision/touching.html index 898f84b8..e7d75ba9 100644 --- a/sandbox/tests/collision/touching.html +++ b/sandbox/tests/collision/touching.html @@ -1,11 +1,10 @@ - + - - - Bloc Breaker - - + + Bloc Breaker + + - + diff --git a/sandbox/tests/collision/touching.ts b/sandbox/tests/collision/touching.ts index 66613fb8..576ce98b 100644 --- a/sandbox/tests/collision/touching.ts +++ b/sandbox/tests/collision/touching.ts @@ -4,13 +4,13 @@ var game = new ex.Engine({ height: 200, width: 800 }); -var paddle = new ex.Actor({x: 150, y: game.drawHeight - 40, width: 200, height: 20, color: ex.Color.Chartreuse}); +var paddle = new ex.Actor({ x: 150, y: game.drawHeight - 40, width: 200, height: 20, color: ex.Color.Chartreuse }); paddle.body.collisionType = ex.CollisionType.Fixed; game.add(paddle); var speed = 300; -var ball = new ex.Actor({x: 150, y: 50, radius: 10, color: ex.Color.Red}); +var ball = new ex.Actor({ x: 150, y: 50, radius: 10, color: ex.Color.Red }); ball.vel.setTo(0, speed); ball.body.collisionType = ex.CollisionType.Active; ball.on('collisionstart', (evt: ex.CollisionStartEvent) => { @@ -21,7 +21,7 @@ ball.on('collisionend', (evt: ex.CollisionEndEvent) => { console.log('Ball was being touched on frame:', game.stats.currFrame.id); evt.actor.vel = ex.vec(0, -speed); }); -ball.on('postupdate', function() { +ball.on('postupdate', function () { if (ball.pos.y < 0) { ball.vel = ex.vec(0, speed); } diff --git a/sandbox/tests/collisionvelocity/vel.html b/sandbox/tests/collisionvelocity/vel.html index d807c42d..b371ec22 100644 --- a/sandbox/tests/collisionvelocity/vel.html +++ b/sandbox/tests/collisionvelocity/vel.html @@ -1,16 +1,16 @@ - + - - - - - Document - - - -
- Velocity vector should not have a y compnent when the box is resting on the platform - - - - \ No newline at end of file + + + + + Document + + + +
+ Velocity vector should not have a y compnent when the box is resting on the platform + + + + diff --git a/sandbox/tests/contentarea/index.html b/sandbox/tests/contentarea/index.html index 997d7ddb..e6038c1f 100644 --- a/sandbox/tests/contentarea/index.html +++ b/sandbox/tests/contentarea/index.html @@ -1,13 +1,13 @@ - + - - - - - ContentArea - - - - - - \ No newline at end of file + + + + + ContentArea + + + + + + diff --git a/sandbox/tests/contentarea/index.ts b/sandbox/tests/contentarea/index.ts index bd2c8d7c..850f4467 100644 --- a/sandbox/tests/contentarea/index.ts +++ b/sandbox/tests/contentarea/index.ts @@ -1,4 +1,3 @@ - var engine = new ex.Engine({ width: 400, height: 400, @@ -29,9 +28,9 @@ engine.currentScene.onPreDraw = (ctx: ex.ExcaliburGraphicsContext) => { const yellow = ex.Color.fromHex('#FDCF45'); const bb = engine.screen.contentArea.clone(); - bb.top++ - bb.left++ - bb.bottom-- + bb.top++; + bb.left++; + bb.bottom--; bb.right--; bb.draw(ctx, ex.Color.Yellow); @@ -40,12 +39,12 @@ engine.currentScene.onPreDraw = (ctx: ex.ExcaliburGraphicsContext) => { ctx.drawCircle(ex.vec(bb.left + 6, bb.bottom - 6), 10, yellow); ctx.drawCircle(ex.vec(bb.right - 6, bb.bottom - 6), 10, red); ctx.restore(); -} +}; engine.add(bounds); engine.add(box); -bounds.on("preupdate", () => { +bounds.on('preupdate', () => { // const topLeft = engine.screen.screenToWorldCoordinates(ex.vec(engine.screen.contentArea.left, engine.screen.contentArea.top)); // const bottomRight = engine.screen.screenToWorldCoordinates(ex.vec(engine.screen.contentArea.right, engine.screen.contentArea.bottom)); // bounds.pos = topLeft; @@ -54,16 +53,15 @@ bounds.on("preupdate", () => { // bounds.graphics.recalculateBounds(); }); -box.on("preupdate", () => { +box.on('preupdate', () => { // box.pos.x = 0;//engine.screen.contentArea.left + 50; // box.pos.y = 0;//engine.screen.contentArea.top + 50; - // console.log(box.pos); }); engine.onPostUpdate = () => { // engine.currentScene.camera.pos = engine.screen.center; -} +}; engine.start().then(() => { console.log(engine.currentScene.camera.pos); diff --git a/sandbox/tests/coordinates/coordinates.ts b/sandbox/tests/coordinates/coordinates.ts index ef47c18c..3dab16e3 100644 --- a/sandbox/tests/coordinates/coordinates.ts +++ b/sandbox/tests/coordinates/coordinates.ts @@ -26,8 +26,13 @@ function addTestPoint(x, y, ax, ay, s = 1, rd = 0, parent = null) { } class Point extends ex.Actor { - constructor(x, y, public expectedX, public expectedY) { - super({x, y, width: 3, height: 3, color: ex.Color.Red}); + constructor( + x, + y, + public expectedX, + public expectedY + ) { + super({ x, y, width: 3, height: 3, color: ex.Color.Red }); } } @@ -36,7 +41,7 @@ class PointLabel extends ex.Actor { private _actualLabel: ex.Label; constructor(public point: Point) { - super({x: 0, y: 0, width: 0, height: 0}); + super({ x: 0, y: 0, width: 0, height: 0 }); this.anchor.setTo(0, 0); } @@ -44,11 +49,11 @@ class PointLabel extends ex.Actor { onInitialize(engine: ex.Engine) { super.onInitialize(engine); - this._expectLabel = new ex.Label({text: '', x: 5, y: 10}); + this._expectLabel = new ex.Label({ text: '', x: 5, y: 10 }); this._expectLabel.color = ex.Color.fromHex('#249111'); this.addChild(this._expectLabel); - this._actualLabel = new ex.Label({text: '', x: 5, y: 20}); + this._actualLabel = new ex.Label({ text: '', x: 5, y: 20 }); this._actualLabel.color = ex.Color.Blue; this.addChild(this._actualLabel); } diff --git a/sandbox/tests/coordinates/index.html b/sandbox/tests/coordinates/index.html index 2140b2c7..d58c24cb 100644 --- a/sandbox/tests/coordinates/index.html +++ b/sandbox/tests/coordinates/index.html @@ -1,17 +1,14 @@ - + - + Coordinates Visual Test - - - + +
-

The calculated world coordinates of each point (BLUE) should match the RED hard-coded label

-
- + diff --git a/sandbox/tests/culling/culling.html b/sandbox/tests/culling/culling.html index aa262561..a4aa796a 100644 --- a/sandbox/tests/culling/culling.html +++ b/sandbox/tests/culling/culling.html @@ -1,14 +1,14 @@ - + - + Actor Culling Test - - + +

Press 'd' for debug mode, arrow keys to move around

Resize the sprite, rotate the actor, etc. The 4 colored corner dots should remain correcly on the 4 corners of the sprite.

player.isOffscreen should only be true if the actor (outlined in yellow in debug mode) and the sprite are both off screen.

- - \ No newline at end of file + + diff --git a/sandbox/tests/culling/culling.ts b/sandbox/tests/culling/culling.ts index 8c792be4..02bee23f 100644 --- a/sandbox/tests/culling/culling.ts +++ b/sandbox/tests/culling/culling.ts @@ -9,7 +9,7 @@ var engine = new ex.Engine({ width: width, height: height, canvasElementId: 'gam engine.backgroundColor = ex.Color.Black; -var player = new ex.Actor({x: width / 2, y: height / 2, width: 30, height: 30, color: ex.Color.Red}); +var player = new ex.Actor({ x: width / 2, y: height / 2, width: 30, height: 30, color: ex.Color.Red }); var playerSprite = playerTexture.toSprite(); player.graphics.add('default', playerSprite); //player.currentDrawing.scale = new ex.Point(0.5, 0.5); diff --git a/sandbox/tests/culling/culling2.html b/sandbox/tests/culling/culling2.html index 4ee04bc5..7d7222e6 100644 --- a/sandbox/tests/culling/culling2.html +++ b/sandbox/tests/culling/culling2.html @@ -1,13 +1,13 @@ - + - + Actor Culling Test on Zoom - - + +

Actors should stay onscreen and not be culled early or late

Check the console, onscreen should be printed when onscreen, and offscreen when offscreen.

- - \ No newline at end of file + + diff --git a/sandbox/tests/culling/culling2.ts b/sandbox/tests/culling/culling2.ts index f5fbab87..b3bd3322 100644 --- a/sandbox/tests/culling/culling2.ts +++ b/sandbox/tests/culling/culling2.ts @@ -15,10 +15,10 @@ var game = new ex.Engine({ // ); // game.add(background); -let person = new ex.Actor({x: 275, y: 250, width: 15, height: 15, color: ex.Color.White}); +let person = new ex.Actor({ x: 275, y: 250, width: 15, height: 15, color: ex.Color.White }); game.add(person); -let soontobeoffscreen = new ex.Actor({x: 375, y: 250, width: 15, height: 15, color: ex.Color.White}); +let soontobeoffscreen = new ex.Actor({ x: 375, y: 250, width: 15, height: 15, color: ex.Color.White }); game.add(soontobeoffscreen); soontobeoffscreen.on('exitviewport', () => { console.log('offscreen'); diff --git a/sandbox/tests/debug/boundingbox.html b/sandbox/tests/debug/boundingbox.html index 1095d3a0..2f12943b 100644 --- a/sandbox/tests/debug/boundingbox.html +++ b/sandbox/tests/debug/boundingbox.html @@ -1,18 +1,15 @@ - + - + Debug - Bounding Boxes Visual Test - - - + +
-

Press D to test debug drawing mode.

You should see bounding boxes for actor and child draw appropriately

-
- + diff --git a/sandbox/tests/debug/boundingbox.ts b/sandbox/tests/debug/boundingbox.ts index 71d64f50..53783099 100644 --- a/sandbox/tests/debug/boundingbox.ts +++ b/sandbox/tests/debug/boundingbox.ts @@ -5,8 +5,8 @@ var game = new ex.Engine({ width: 500, height: 500 }); game.showDebug(true); game.start().then(() => { - var parent = new ex.Actor({x: 100, y: 100, width: 100 * 1.5, height: 100 * 1.5, color: ex.Color.Red}); - var child = new ex.Actor({x: 150, y: 150, width: 100, height: 100, color: ex.Color.White}); + var parent = new ex.Actor({ x: 100, y: 100, width: 100 * 1.5, height: 100 * 1.5, color: ex.Color.Red }); + var child = new ex.Actor({ x: 150, y: 150, width: 100, height: 100, color: ex.Color.White }); parent.addChild(child); game.add(parent); }); diff --git a/sandbox/tests/debug/stats.html b/sandbox/tests/debug/stats.html index ba1c50bc..f8f0bff4 100644 --- a/sandbox/tests/debug/stats.html +++ b/sandbox/tests/debug/stats.html @@ -1,43 +1,47 @@ - + - + Debug - Stats Visual Test - - - + +
-

Stats:

    -
  • Delta: (avg: )
  • -
  • FPS: (avg: )
  • +
  • Delta: (avg: )
  • +
  • FPS: (avg: )
  • -
  • Duration - Total (ms):
  • -
  • Duration - Draw (ms):
  • -
  • Duration - Update (ms):
  • +
  • Duration - Total (ms):
  • +
  • Duration - Draw (ms):
  • +
  • Duration - Update (ms):
  • -
  • Actors - Total:
  • -
  • Actors - Alive:
  • -
  • Actors - Killed:
  • -
  • Actors - Remaining:
  • -
  • Actors - UI:
  • +
  • Actors - Total:
  • +
  • Actors - Alive:
  • +
  • Actors - Killed:
  • +
  • Actors - Remaining:
  • +
  • Actors - UI:
  • -
  • Physics - Pairs:
  • -
  • Physics - Collisions:
  • -
  • Physics - Fast Bodies:
  • -
  • Physics - Fast Body Collisions:
  • -
  • Physics - Broadphase (ms):
  • -
  • Physics - Narrowphase (ms):
  • +
  • Physics - Pairs:
  • +
  • Physics - Collisions:
  • +
  • Physics - Fast Bodies:
  • +
  • Physics - Fast Body Collisions:
  • +
  • Physics - Broadphase (ms):
  • +
  • Physics - Narrowphase (ms):
-
- + diff --git a/sandbox/tests/debug/stats.ts b/sandbox/tests/debug/stats.ts index aae1d394..e2d2bb7f 100644 --- a/sandbox/tests/debug/stats.ts +++ b/sandbox/tests/debug/stats.ts @@ -6,11 +6,11 @@ ex.Physics.acc.setTo(0, 500); var historicFrameStats = new Array(10); -var updateStat = function(id, stat) { +var updateStat = function (id, stat) { document.getElementById(id).innerHTML = stat; }; -var avg = function(arr: Array, prop: string) { +var avg = function (arr: Array, prop: string) { var sum = 0; var i = 0; @@ -62,10 +62,10 @@ game.on('postframe', (ev: ex.PostFrameEvent) => { updateStat('debug-frame-narrowphase', ev.stats.physics.narrowphase); }); -game.add(new ex.ScreenElement({width: 50, height: 50})); +game.add(new ex.ScreenElement({ width: 50, height: 50 })); function spawnBox() { - var box = new ex.Actor({x: 250, y: 50, width: 50, height: 50, color: ex.Color.Red}); + var box = new ex.Actor({ x: 250, y: 50, width: 50, height: 50, color: ex.Color.Red }); box.body.collisionType = ex.CollisionType.Active; box.collider.useBoxCollider(50, 50); game.add(box); @@ -73,7 +73,7 @@ function spawnBox() { spawnBox(); -var floor = new ex.Actor({x: 250, y: 500, width: 500, height: 10, color: ex.Color.Green}); +var floor = new ex.Actor({ x: 250, y: 500, width: 500, height: 10, color: ex.Color.Green }); floor.body.collisionType = ex.CollisionType.Fixed; floor.collider.useBoxCollider(50, 50); game.add(floor); diff --git a/sandbox/tests/decode-many/index.html b/sandbox/tests/decode-many/index.html index ad24b824..87da3681 100644 --- a/sandbox/tests/decode-many/index.html +++ b/sandbox/tests/decode-many/index.html @@ -1,14 +1,14 @@ - + - - - - - Decode Images - - -

There should be no errors in the console relating to loading images

- - - - \ No newline at end of file + + + + + Decode Images + + +

There should be no errors in the console relating to loading images

+ + + + diff --git a/sandbox/tests/decode-many/index.ts b/sandbox/tests/decode-many/index.ts index 5e6b7a37..56a31add 100644 --- a/sandbox/tests/decode-many/index.ts +++ b/sandbox/tests/decode-many/index.ts @@ -10,16 +10,16 @@ function generate() { for (let i = 0; i < 800; i++) { srcs.push(generateRandomImage()); } - let images = srcs.map(src => new ex.ImageSource(src)); + let images = srcs.map((src) => new ex.ImageSource(src)); loader.addResources(images); - let sprites = images.map(i => i.toSprite()); + let sprites = images.map((i) => i.toSprite()); - game.currentScene.onPostDraw = ctx => { + game.currentScene.onPostDraw = (ctx) => { ctx.save(); - ctx.scale(.25, .25); + ctx.scale(0.25, 0.25); for (let i = 0; i < sprites.length; i++) { - sprites[i].draw(ctx, (i * 100) % (800 * 4) + 10, Math.floor((i * 100) / (800 * 4)) * 100 + 10); + sprites[i].draw(ctx, ((i * 100) % (800 * 4)) + 10, Math.floor((i * 100) / (800 * 4)) * 100 + 10); } ctx.restore(); }; @@ -36,28 +36,25 @@ function drawRandomCircleOnContext(ctx) { ctx.beginPath(); ctx.arc(x, y, radius, Math.PI * 2, 0, false); - ctx.fillStyle = "rgba(" + r + "," + g + "," + b + ",1)"; + ctx.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',1)'; ctx.fill(); ctx.closePath(); } function generateRandomImage() { - const canvas = document.createElement("canvas"); + const canvas = document.createElement('canvas'); canvas.width = 100; canvas.height = 100; - const ctx = canvas.getContext("2d"); + const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, 100, 100); for (let i = 0; i < 20; i++) { drawRandomCircleOnContext(ctx); } - return canvas.toDataURL("image/png"); + return canvas.toDataURL('image/png'); } - generate(); - - -game.start(loader); \ No newline at end of file +game.start(loader); diff --git a/sandbox/tests/drawcalls/index.html b/sandbox/tests/drawcalls/index.html index 5cb34648..a4ed2442 100644 --- a/sandbox/tests/drawcalls/index.html +++ b/sandbox/tests/drawcalls/index.html @@ -1,19 +1,19 @@ - + - - - - - Test Draw Call Limits and Orderings - - - -
-
Draw Calls:0
-
# Items:0
- -
- - - - \ No newline at end of file + + + + + Test Draw Call Limits and Orderings + + + +
+
Draw Calls:0
+
# Items:0
+ +
+ + + + diff --git a/sandbox/tests/drawcalls/index.ts b/sandbox/tests/drawcalls/index.ts index d9eb870f..98592b4b 100644 --- a/sandbox/tests/drawcalls/index.ts +++ b/sandbox/tests/drawcalls/index.ts @@ -1,6 +1,5 @@ /// - var game = new ex.Engine({ canvasElementId: 'game', width: 600, @@ -13,7 +12,7 @@ var loader = new ex.Loader([tex]); var random = new ex.Random(1337); -var items = [{pos: ex.Vector.Zero, vel: ex.vec(random.integer(50, 100), random.integer(50, 100))}]; +var items = [{ pos: ex.Vector.Zero, vel: ex.vec(random.integer(50, 100), random.integer(50, 100)) }]; var drawCalls$ = document.getElementById('draw-calls'); var drawnItems$ = document.getElementById('drawn-items'); var add$ = document.getElementById('add'); @@ -31,12 +30,12 @@ game.start(loader).then(() => { const height = tex.height; game.onPostUpdate = (_engine, deltaMs) => { for (let i = 0; i < items.length; i++) { - items[i].pos.addEqual(items[i].vel.scale(deltaMs/1000)); - if ((items[i].pos.x + width / 2) > 600 || items[i].pos.x < 0) { + items[i].pos.addEqual(items[i].vel.scale(deltaMs / 1000)); + if (items[i].pos.x + width / 2 > 600 || items[i].pos.x < 0) { items[i].vel.x *= -1; } - if ((items[i].pos.y + height / 2) > 400 || items[i].pos.y < 0) { + if (items[i].pos.y + height / 2 > 400 || items[i].pos.y < 0) { items[i].vel.y *= -1; } } @@ -47,9 +46,7 @@ game.start(loader).then(() => { const blue = ex.Color.Blue; const black = ex.Color.Black; for (let i = 0; i < items.length; i++) { - game.graphicsContext.drawImage(tex.image, - 0, 0, width, height, - items[i].pos.x, items[i].pos.y, width / 2, height / 2); + game.graphicsContext.drawImage(tex.image, 0, 0, width, height, items[i].pos.x, items[i].pos.y, width / 2, height / 2); // game.graphicsContext.drawCircle(items[i].pos, width / 4, blue, black, 2); // game.graphicsContext.drawRectangle(items[i].pos, width, height, blue, black, 2); diff --git a/sandbox/tests/ecs/index.html b/sandbox/tests/ecs/index.html index cf0b7c13..9a9d5509 100644 --- a/sandbox/tests/ecs/index.html +++ b/sandbox/tests/ecs/index.html @@ -1,13 +1,13 @@ - + - - - - ECS Test - - - - - - - \ No newline at end of file + + + + ECS Test + + + + + + + diff --git a/sandbox/tests/ecs/index.ts b/sandbox/tests/ecs/index.ts index 5d10dd44..74e84bca 100644 --- a/sandbox/tests/ecs/index.ts +++ b/sandbox/tests/ecs/index.ts @@ -8,21 +8,20 @@ class Game5 { constructor() { this.player.addComponent(new ex.TransformComponent()); - this.player.addComponent(new ex.GraphicsComponent({ - current: 'triangle', - graphics: { - triangle: new ex.Polygon({ - points: [ - ex.vec(-64, -64), - ex.vec(64, 0), - ex.vec(-64, 64), - ], - color: ex.Color.Red, - strokeColor: ex.Color.Black, - padding: 2 - }), - } - }), true); // Force replacement + this.player.addComponent( + new ex.GraphicsComponent({ + current: 'triangle', + graphics: { + triangle: new ex.Polygon({ + points: [ex.vec(-64, -64), ex.vec(64, 0), ex.vec(-64, 64)], + color: ex.Color.Red, + strokeColor: ex.Color.Black, + padding: 2 + }) + } + }), + true + ); // Force replacement } public async start() { @@ -48,4 +47,4 @@ class Game5 { } var game5 = new Game5(); -game5.start(); \ No newline at end of file +game5.start(); diff --git a/sandbox/tests/emitter/index.html b/sandbox/tests/emitter/index.html index e55a8a14..b630d586 100644 --- a/sandbox/tests/emitter/index.html +++ b/sandbox/tests/emitter/index.html @@ -1,13 +1,13 @@ - + - - - - - Emitter - - - - - - \ No newline at end of file + + + + + Emitter + + + + + + diff --git a/sandbox/tests/emitter/index.ts b/sandbox/tests/emitter/index.ts index a4be03c8..737f864d 100644 --- a/sandbox/tests/emitter/index.ts +++ b/sandbox/tests/emitter/index.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 400, height: 400 @@ -8,10 +7,10 @@ var actor = new ex.Actor({ anchor: ex.vec(0.5, 0.5), pos: game.screen.center, color: ex.Color.Red, - radius: 5, + radius: 5 }); -actor.actions.repeatForever(ctx => { +actor.actions.repeatForever((ctx) => { ctx.moveBy(ex.vec(100, 100), 100); ctx.moveBy(ex.vec(-100, -100), 100); }); diff --git a/sandbox/tests/engine/timescale.html b/sandbox/tests/engine/timescale.html index 4b0f5416..61c0a3a8 100644 --- a/sandbox/tests/engine/timescale.html +++ b/sandbox/tests/engine/timescale.html @@ -1,12 +1,10 @@ - + - + Engine - Timescale Visual Test - - - + +
-

Press S to reduce timescale by 10%.

Press W to increase timescale by 10%.

Current Timescale:

@@ -14,5 +12,5 @@ - + diff --git a/sandbox/tests/engine/timescale.ts b/sandbox/tests/engine/timescale.ts index 25885ad3..6c8bdc85 100644 --- a/sandbox/tests/engine/timescale.ts +++ b/sandbox/tests/engine/timescale.ts @@ -18,11 +18,10 @@ game.on('postupdate', () => { }); game.start().then(() => { - var rect = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red}); + var rect = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red }); - rect.actions.repeatForever(ctx => { - ctx.easeTo(300, 200, 600, ex.EasingFunctions.EaseOutCubic) - .easeTo(200, 200, 600, ex.EasingFunctions.EaseOutCubic) + rect.actions.repeatForever((ctx) => { + ctx.easeTo(300, 200, 600, ex.EasingFunctions.EaseOutCubic).easeTo(200, 200, 600, ex.EasingFunctions.EaseOutCubic); }); game.add(rect); diff --git a/sandbox/tests/fitscreen/fitscreen.ts b/sandbox/tests/fitscreen/fitscreen.ts index 17d85e90..fe8ae7aa 100644 --- a/sandbox/tests/fitscreen/fitscreen.ts +++ b/sandbox/tests/fitscreen/fitscreen.ts @@ -1,34 +1,33 @@ - async function main() { - const game = new ex.Engine({ - width: 3000, - height: 3000, - suppressHiDPIScaling: true, - displayMode: ex.DisplayMode.FitScreen, - }); + const game = new ex.Engine({ + width: 3000, + height: 3000, + suppressHiDPIScaling: true, + displayMode: ex.DisplayMode.FitScreen + }); - await game.start(); + await game.start(); - const paddle = new ex.Actor({ - x: 220, - y: 220, - width: 400, - height: 400, - color: ex.Color.White, - }); + const paddle = new ex.Actor({ + x: 220, + y: 220, + width: 400, + height: 400, + color: ex.Color.White + }); - console.log('Game:', game.drawWidth, '·', game.drawHeight); - console.log('Canv:', game.canvasWidth, '·', game.canvasHeight); - // console.log('Camera: ', game.currentScene.camera.pos); - // console.log('Center: ', game.screen.center); - // game.currentScene.camera.pos = game.screen.center; + console.log('Game:', game.drawWidth, '·', game.drawHeight); + console.log('Canv:', game.canvasWidth, '·', game.canvasHeight); + // console.log('Camera: ', game.currentScene.camera.pos); + // console.log('Center: ', game.screen.center); + // game.currentScene.camera.pos = game.screen.center; - game.add(paddle); - return [game, paddle]; + game.add(paddle); + return [game, paddle]; } main().then(([game, paddle]) => { - console.log('Promise from main()'); - (window as any).game = game; - (window as any).paddle = paddle; -}); \ No newline at end of file + console.log('Promise from main()'); + (window as any).game = game; + (window as any).paddle = paddle; +}); diff --git a/sandbox/tests/fitscreen/index.html b/sandbox/tests/fitscreen/index.html index f79f1d27..0d7c8e85 100644 --- a/sandbox/tests/fitscreen/index.html +++ b/sandbox/tests/fitscreen/index.html @@ -1,24 +1,24 @@ - + - - - - - FitScreen - - - - - - - \ No newline at end of file + } + + + + + + + diff --git a/sandbox/tests/gif/animatedGif.html b/sandbox/tests/gif/animatedGif.html index 9915bee2..344e4380 100644 --- a/sandbox/tests/gif/animatedGif.html +++ b/sandbox/tests/gif/animatedGif.html @@ -1,15 +1,15 @@ - + - - - - - Document - - - -
Open the console there should be no errors in firefox or chrome - - - + + + + + Document + + + +
Open the console there should be no errors in firefox or chrome + + + diff --git a/sandbox/tests/gif/animatedGif.ts b/sandbox/tests/gif/animatedGif.ts index a01335d3..b355e01b 100644 --- a/sandbox/tests/gif/animatedGif.ts +++ b/sandbox/tests/gif/animatedGif.ts @@ -13,7 +13,7 @@ game.currentScene.camera.zoom = 2; var gif: ex.Gif = new ex.Gif('./sword.gif', ex.Color.Black); var loader = new ex.Loader([gif]); game.start(loader).then(() => { - var actor = new ex.Actor({x: game.currentScene.camera.x, y: game.currentScene.camera.y, width: gif.width, height: gif.height}); + var actor = new ex.Actor({ x: game.currentScene.camera.x, y: game.currentScene.camera.y, width: gif.width, height: gif.height }); actor.graphics.add(gif.toAnimation(500)); game.add(actor); }); diff --git a/sandbox/tests/gotoscene/index.html b/sandbox/tests/gotoscene/index.html index a81762b9..0748a389 100644 --- a/sandbox/tests/gotoscene/index.html +++ b/sandbox/tests/gotoscene/index.html @@ -1,14 +1,14 @@ - + - - - - - Go To Scene - - - - - - - \ No newline at end of file + + + + + Go To Scene + + + + + + + diff --git a/sandbox/tests/gotoscene/index.ts b/sandbox/tests/gotoscene/index.ts index 47562a15..dc6f3b1d 100644 --- a/sandbox/tests/gotoscene/index.ts +++ b/sandbox/tests/gotoscene/index.ts @@ -8,24 +8,20 @@ class Scene1 extends ex.Scene { y: _engine.halfDrawHeight, width: 20, height: 20, - color: ex.Color.Magenta, + color: ex.Color.Magenta }); this.add(actor); - _engine.input.pointers.primary.on( - "down", - async (event: ex.PointerEvent) => { - await _engine.goToScene("scene2"); - } - ); + _engine.input.pointers.primary.on('down', async (event: ex.PointerEvent) => { + await _engine.goToScene('scene2'); + }); } async onActivate() { - console.log('Scene 1 Activate') + console.log('Scene 1 Activate'); } } - class Scene2 extends ex.Scene { async onInitialize(_engine: ex.Engine) { await ex.Util.delay(1000); @@ -34,30 +30,29 @@ class Scene2 extends ex.Scene { pos: ex.Vector.Zero, width: 1000, height: 1000, - color: ex.Color.Cyan, + color: ex.Color.Cyan }); actor.angularVelocity = 1; _engine.add(actor); } async onActivate() { await ex.Util.delay(1000); - console.log('Scene 2 Activate') + console.log('Scene 2 Activate'); } } - var engine = new ex.Engine({ width: 1920 / 2, height: 1080 / 2, - canvasElementId: "game", + canvasElementId: 'game' }); -engine.add("scene1", new Scene1()); -engine.add("scene2", new Scene2()); -engine.goToScene("scene1"); +engine.add('scene1', new Scene1()); +engine.add('scene2', new Scene2()); +engine.goToScene('scene1'); var loader = new ex.Loader(); loader.suppressPlayButton = true; -engine.start(loader); \ No newline at end of file +engine.start(loader); diff --git a/sandbox/tests/graphics-group/index.html b/sandbox/tests/graphics-group/index.html index 027d22fd..8442f96c 100644 --- a/sandbox/tests/graphics-group/index.html +++ b/sandbox/tests/graphics-group/index.html @@ -1,13 +1,13 @@ - + - - - - - Graphics Padding Test - - - - - - \ No newline at end of file + + + + + Graphics Padding Test + + + + + + diff --git a/sandbox/tests/graphics-group/index.ts b/sandbox/tests/graphics-group/index.ts index c19c2946..67517fe9 100644 --- a/sandbox/tests/graphics-group/index.ts +++ b/sandbox/tests/graphics-group/index.ts @@ -11,7 +11,7 @@ game.debug.transform.showPosition = true; var heartImage = new ex.ImageSource('./heart.png'); -var loader = new ex.Loader([heartImage]) +var loader = new ex.Loader([heartImage]); class MyActor2 extends ex.Actor { constructor() { @@ -21,38 +21,38 @@ class MyActor2 extends ex.Actor { } onInitialize() { this.graphics.add( - "interactive", + 'interactive', new ex.GraphicsGroup({ useAnchor: false, members: [ { graphic: heartImage.toSprite(), - offset: ex.vec(0, 0), + offset: ex.vec(0, 0) }, { graphic: heartImage.toSprite(), - offset: ex.vec(0, 16), + offset: ex.vec(0, 16) }, { graphic: heartImage.toSprite(), - offset: ex.vec(16, 16), + offset: ex.vec(16, 16) }, { graphic: heartImage.toSprite(), - offset: ex.vec(16, 0), - }, - ], + offset: ex.vec(16, 0) + } + ] }) ); } onPreUpdate(engine: ex.Engine, delta: number): void { - this.graphics.use("interactive"); + this.graphics.use('interactive'); } } game.add(new MyActor2()); -game.start(loader) +game.start(loader); game.currentScene.camera.pos = ex.vec(200, 200); -game.currentScene.camera.zoom = 3; \ No newline at end of file +game.currentScene.camera.zoom = 3; diff --git a/sandbox/tests/graphics/index.html b/sandbox/tests/graphics/index.html index 027d22fd..8442f96c 100644 --- a/sandbox/tests/graphics/index.html +++ b/sandbox/tests/graphics/index.html @@ -1,13 +1,13 @@ - + - - - - - Graphics Padding Test - - - - - - \ No newline at end of file + + + + + Graphics Padding Test + + + + + + diff --git a/sandbox/tests/graphics/index.ts b/sandbox/tests/graphics/index.ts index 65390fc7..358c83ed 100644 --- a/sandbox/tests/graphics/index.ts +++ b/sandbox/tests/graphics/index.ts @@ -1,16 +1,13 @@ /// - /** * Managed game class */ class Game extends ex.Engine { - constructor() { super({ displayMode: ex.DisplayMode.FillScreen, - enableCanvasTransparency: true, - + enableCanvasTransparency: true }); } @@ -22,14 +19,12 @@ class Game extends ex.Engine { strokeColor: ex.Color.DarkGray, lineWidth: 10, // padding: 20, - smoothing: true, - + smoothing: true }); actor.graphics.add(circle); scene.add(actor); this.add('levelOne', scene); - // Automatically load all default resources const loader = new ex.Loader(); this.simulate(circle); @@ -50,4 +45,3 @@ var game3 = new Game(); game3.start().then(() => { game3.goToScene('levelOne'); }); - diff --git a/sandbox/tests/graphicscontext/index.html b/sandbox/tests/graphicscontext/index.html index cfde743e..7f2fa82e 100644 --- a/sandbox/tests/graphicscontext/index.html +++ b/sandbox/tests/graphicscontext/index.html @@ -1,12 +1,12 @@ - + - - - - Graphics Context - - - - - - \ No newline at end of file + + + + Graphics Context + + + + + + diff --git a/sandbox/tests/graphicscontext/index.ts b/sandbox/tests/graphicscontext/index.ts index b9d33203..431de2b8 100644 --- a/sandbox/tests/graphicscontext/index.ts +++ b/sandbox/tests/graphicscontext/index.ts @@ -22,7 +22,7 @@ var rect = new ex.Rectangle({ sut.beginDrawLifecycle(); sut.clear(); -sut.save() +sut.save(); sut.drawImage(rect._bitmap, 20, 20); sut.restore(); diff --git a/sandbox/tests/group/group.ts b/sandbox/tests/group/group.ts index 42dd5596..8eb5a1ca 100644 --- a/sandbox/tests/group/group.ts +++ b/sandbox/tests/group/group.ts @@ -1,62 +1,56 @@ /// -(function() { - - - -var width = 600; -var height = 400; -var minVel = -200; -var maxVel = 200; -var numActors = 300; -var blockTexture = new ex.ImageSource('block.png'); -var engine = new ex.Engine({ width: width, height: height, canvasElementId: 'game' }); -//engine.showDebug(true); -ex.Physics.useRealisticPhysics(); -var blockGroup = ex.CollisionGroupManager.create('blocks'); -var blockSprite2 = blockTexture.toSprite(); -blockSprite2.scale.setTo(0.2, 0.2); - -var player = new ex.Actor({x: width / 2, y: height / 2, width: 30, height: 30, color: ex.Color.Cyan}); -player.body.collisionType = ex.CollisionType.Fixed; -player.body.group = ex.CollisionGroupManager.create('player'); -engine.currentScene.add(player); - -for (var i = 0; i < numActors; i++) { - var actor = new ex.Actor({x: Math.random() * width, y: Math.random() * height, width: 0.2 * 64, height: 0.2 * 48}); - - actor.graphics.add(blockSprite2.clone()); - - actor.body.collisionType = ex.CollisionType.Active; - actor.body.group = blockGroup; - actor.on('postupdate', (e: ex.PostUpdateEvent) => { - if (actor.pos.x < 0) { - actor.vel.x = Math.abs(actor.vel.x); - } - - if (actor.pos.y < 0) { - actor.vel.y = Math.abs(actor.vel.y); - } - - if (actor.pos.x > width) { - actor.vel.x = -1 * Math.abs(actor.vel.x); - } - - if (actor.pos.y > height) { - actor.vel.y = -1 * Math.abs(actor.vel.y); - } +(function () { + var width = 600; + var height = 400; + var minVel = -200; + var maxVel = 200; + var numActors = 300; + var blockTexture = new ex.ImageSource('block.png'); + var engine = new ex.Engine({ width: width, height: height, canvasElementId: 'game' }); + //engine.showDebug(true); + ex.Physics.useRealisticPhysics(); + var blockGroup = ex.CollisionGroupManager.create('blocks'); + var blockSprite2 = blockTexture.toSprite(); + blockSprite2.scale.setTo(0.2, 0.2); + + var player = new ex.Actor({ x: width / 2, y: height / 2, width: 30, height: 30, color: ex.Color.Cyan }); + player.body.collisionType = ex.CollisionType.Fixed; + player.body.group = ex.CollisionGroupManager.create('player'); + engine.currentScene.add(player); + + for (var i = 0; i < numActors; i++) { + var actor = new ex.Actor({ x: Math.random() * width, y: Math.random() * height, width: 0.2 * 64, height: 0.2 * 48 }); + + actor.graphics.add(blockSprite2.clone()); + + actor.body.collisionType = ex.CollisionType.Active; + actor.body.group = blockGroup; + actor.on('postupdate', (e: ex.PostUpdateEvent) => { + if (actor.pos.x < 0) { + actor.vel.x = Math.abs(actor.vel.x); + } + + if (actor.pos.y < 0) { + actor.vel.y = Math.abs(actor.vel.y); + } + + if (actor.pos.x > width) { + actor.vel.x = -1 * Math.abs(actor.vel.x); + } + + if (actor.pos.y > height) { + actor.vel.y = -1 * Math.abs(actor.vel.y); + } + }); + + actor.on('postcollision', (e: ex.PostCollisionEvent) => {}); + + actor.vel = ex.vec(ex.randomInRange(minVel, maxVel), ex.randomInRange(minVel, maxVel)); + engine.add(actor); + } + + engine.start(new ex.Loader([blockTexture])).then(() => { + // do stuff }); - - actor.on('postcollision', (e: ex.PostCollisionEvent) => { - - }); - - actor.vel = ex.vec(ex.randomInRange(minVel, maxVel), ex.randomInRange(minVel, maxVel)); - engine.add(actor); -} - -engine.start(new ex.Loader([blockTexture])).then(() => { - // do stuff -}); - -})(); \ No newline at end of file +})(); diff --git a/sandbox/tests/group/index.html b/sandbox/tests/group/index.html index e49b824d..442f8b2d 100644 --- a/sandbox/tests/group/index.html +++ b/sandbox/tests/group/index.html @@ -1,12 +1,12 @@ - + - + - - + +

The orange blocks should not collide with each other, but they should collide with the teal square in the center of the screen

- - \ No newline at end of file + + diff --git a/sandbox/tests/iframe/frame.html b/sandbox/tests/iframe/frame.html index 7216ee26..034c6485 100644 --- a/sandbox/tests/iframe/frame.html +++ b/sandbox/tests/iframe/frame.html @@ -1,13 +1,13 @@ - + - - - - - Frame - - - - - - \ No newline at end of file + + + + + Frame + + + + + + diff --git a/sandbox/tests/iframe/index.html b/sandbox/tests/iframe/index.html index a8eaddb1..a67d11cc 100644 --- a/sandbox/tests/iframe/index.html +++ b/sandbox/tests/iframe/index.html @@ -1,13 +1,13 @@ - + - - - - - Document - - - - - - \ No newline at end of file + + + + + Document + + + + + + diff --git a/sandbox/tests/iframe/main.ts b/sandbox/tests/iframe/main.ts index 125f99dc..45b6527e 100644 --- a/sandbox/tests/iframe/main.ts +++ b/sandbox/tests/iframe/main.ts @@ -3,7 +3,6 @@ // console.log(evt.code); // }) - var engine = new ex.Engine({ width: 600, height: 400 @@ -16,6 +15,6 @@ engine.input.keyboard.on('press', (evt) => { engine.onPostDraw = (ctx: ex.ExcaliburGraphicsContext) => { const keys = engine.input.keyboard.getKeys(); ctx.debug.drawText(keys.join(','), ex.vec(200, 200)); -} +}; -engine.start(); \ No newline at end of file +engine.start(); diff --git a/sandbox/tests/imageloading/index.html b/sandbox/tests/imageloading/index.html index 81634df4..a0c018a4 100644 --- a/sandbox/tests/imageloading/index.html +++ b/sandbox/tests/imageloading/index.html @@ -1,13 +1,13 @@ - + - - - - - Image Loading - - - - - - \ No newline at end of file + + + + + Image Loading + + + + + + diff --git a/sandbox/tests/imageloading/index.ts b/sandbox/tests/imageloading/index.ts index 134ab6f9..909291f9 100644 --- a/sandbox/tests/imageloading/index.ts +++ b/sandbox/tests/imageloading/index.ts @@ -1,6 +1,5 @@ /// - var game = new ex.Engine({ width: 600, height: 400 @@ -13,4 +12,4 @@ game.on('postdraw', () => { game.graphicsContext.drawImage(image.image, 0, 0); }); -game.start(loader); \ No newline at end of file +game.start(loader); diff --git a/sandbox/tests/imagewrapping/index.html b/sandbox/tests/imagewrapping/index.html index 45b4bf43..7dd441e0 100644 --- a/sandbox/tests/imagewrapping/index.html +++ b/sandbox/tests/imagewrapping/index.html @@ -1,13 +1,13 @@ - + - - - - Image Wrapping - - - - - - - \ No newline at end of file + + + + Image Wrapping + + + + + + + diff --git a/sandbox/tests/imagewrapping/index.ts b/sandbox/tests/imagewrapping/index.ts index d7cbcfe4..82635335 100644 --- a/sandbox/tests/imagewrapping/index.ts +++ b/sandbox/tests/imagewrapping/index.ts @@ -1,7 +1,7 @@ /// // identity tagged template literal lights up glsl-literal vscode plugin -var glsl = x => x[0]; +var glsl = (x) => x[0]; var game = new ex.Engine({ canvasElementId: 'game', width: 800, @@ -29,7 +29,7 @@ var fireShader = glsl`#version 300 es fragColor.a = color.r; fragColor.rgb = fragColor.rgb * fragColor.a; } -` +`; var noiseImage = new ex.ImageSource('./noise.png', { filtering: ex.ImageFiltering.Blended, @@ -40,9 +40,9 @@ var material = game.graphicsContext.createMaterial({ name: 'fire', fragmentSource: fireShader, images: { - 'noise': noiseImage + noise: noiseImage } -}) +}); var actor = new ex.Actor({ pos: ex.vec(0, 200), @@ -56,4 +56,4 @@ game.add(actor); var loader = new ex.Loader([noiseImage]); -game.start(loader); \ No newline at end of file +game.start(loader); diff --git a/sandbox/tests/incorrectside/index.html b/sandbox/tests/incorrectside/index.html index 714ba6ae..eb6465b5 100644 --- a/sandbox/tests/incorrectside/index.html +++ b/sandbox/tests/incorrectside/index.html @@ -1,13 +1,13 @@ - + - - - - - Incorrect Side - - - - - - \ No newline at end of file + + + + + Incorrect Side + + + + + + diff --git a/sandbox/tests/incorrectside/index.ts b/sandbox/tests/incorrectside/index.ts index 6f55e95e..05b58e57 100644 --- a/sandbox/tests/incorrectside/index.ts +++ b/sandbox/tests/incorrectside/index.ts @@ -10,7 +10,7 @@ class Player4 extends ex.Actor { constructor() { super({ - name: "player", + name: 'player', x: 200, y: 200, width: 40, @@ -19,7 +19,7 @@ class Player4 extends ex.Actor { collisionType: ex.CollisionType.Active }); - this.on("precollision", (ev) => this.onPreCollision(ev)); + this.on('precollision', (ev) => this.onPreCollision(ev)); } onPreCollision(ev) { diff --git a/sandbox/tests/input-mapper/index.html b/sandbox/tests/input-mapper/index.html index 39752728..3e2f7067 100644 --- a/sandbox/tests/input-mapper/index.html +++ b/sandbox/tests/input-mapper/index.html @@ -1,12 +1,12 @@ - + - - - - Input Mapping - - - - - - \ No newline at end of file + + + + Input Mapping + + + + + + diff --git a/sandbox/tests/input-mapper/main.ts b/sandbox/tests/input-mapper/main.ts index da6baf1f..8aedd6b4 100644 --- a/sandbox/tests/input-mapper/main.ts +++ b/sandbox/tests/input-mapper/main.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 600, height: 400, @@ -13,52 +12,61 @@ var actor = new ex.Actor({ }); var moveRight = (amount: number) => { actor.vel.x = 100 * amount; -} +}; var moveLeft = (amount: number) => { actor.vel.x = -100 * amount; -} +}; var moveUp = (amount: number) => { actor.vel.y = -100 * amount; -} +}; var moveDown = (amount: number) => { actor.vel.y = 100 * amount; -} +}; var getLeftStickX = (gamepad: ex.Gamepad) => { - return gamepad.getAxes(ex.Axes.LeftStickX) -} + return gamepad.getAxes(ex.Axes.LeftStickX); +}; var getLeftStickY = (gamepad: ex.Gamepad) => { - return gamepad.getAxes(ex.Axes.LeftStickY) -} + return gamepad.getAxes(ex.Axes.LeftStickY); +}; actor.onInitialize = (engine) => { const mapper = engine.inputMapper; - ex.Gamepads.MinAxisMoveThreshold = .10; + ex.Gamepads.MinAxisMoveThreshold = 0.1; // Move right - mapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.Right) ? 1 : 0, moveRight); - mapper.on(({gamepads}) => gamepads.at(0).getButton(ex.Buttons.DpadRight) ? 1 : 0, moveRight); - mapper.on(({gamepads}) => getLeftStickX(gamepads.at(0)) > 0 ? Math.abs(getLeftStickX(gamepads.at(0))) : 0, moveRight); - mapper.on(({keyboard, pointers}) => keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.x > actor.pos.x ? 1 : 0, moveRight); + mapper.on(({ keyboard }) => (keyboard.isHeld(ex.Keys.Right) ? 1 : 0), moveRight); + mapper.on(({ gamepads }) => (gamepads.at(0).getButton(ex.Buttons.DpadRight) ? 1 : 0), moveRight); + mapper.on(({ gamepads }) => (getLeftStickX(gamepads.at(0)) > 0 ? Math.abs(getLeftStickX(gamepads.at(0))) : 0), moveRight); + mapper.on( + ({ keyboard, pointers }) => (keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.x > actor.pos.x ? 1 : 0), + moveRight + ); // Move left - mapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.Left) ? 1 : 0, moveLeft); - mapper.on(({gamepads}) => gamepads.at(0).getButton(ex.Buttons.DpadLeft) ? 1 : 0, moveLeft); - mapper.on(({gamepads}) => getLeftStickX(gamepads.at(0)) < 0 ? Math.abs(getLeftStickX(gamepads.at(0))): 0, moveLeft); - mapper.on(({keyboard, pointers}) => keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.x < actor.pos.x ? 1 : 0, moveLeft); + mapper.on(({ keyboard }) => (keyboard.isHeld(ex.Keys.Left) ? 1 : 0), moveLeft); + mapper.on(({ gamepads }) => (gamepads.at(0).getButton(ex.Buttons.DpadLeft) ? 1 : 0), moveLeft); + mapper.on(({ gamepads }) => (getLeftStickX(gamepads.at(0)) < 0 ? Math.abs(getLeftStickX(gamepads.at(0))) : 0), moveLeft); + mapper.on( + ({ keyboard, pointers }) => (keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.x < actor.pos.x ? 1 : 0), + moveLeft + ); // Move up - mapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.Up) ? 1 : 0, moveUp); - mapper.on(({gamepads}) => gamepads.at(0).getButton(ex.Buttons.DpadUp) ? 1 : 0, moveUp); - mapper.on(({gamepads}) => getLeftStickY(gamepads.at(0)) < 0 ? Math.abs(getLeftStickY(gamepads.at(0))) : 0, moveUp); - mapper.on(({keyboard, pointers}) => keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.y < actor.pos.y ? 1 : 0, moveUp); + mapper.on(({ keyboard }) => (keyboard.isHeld(ex.Keys.Up) ? 1 : 0), moveUp); + mapper.on(({ gamepads }) => (gamepads.at(0).getButton(ex.Buttons.DpadUp) ? 1 : 0), moveUp); + mapper.on(({ gamepads }) => (getLeftStickY(gamepads.at(0)) < 0 ? Math.abs(getLeftStickY(gamepads.at(0))) : 0), moveUp); + mapper.on(({ keyboard, pointers }) => (keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.y < actor.pos.y ? 1 : 0), moveUp); // Move down - mapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.Down) ? 1 : 0, moveDown); - mapper.on(({gamepads}) => gamepads.at(0).getButton(ex.Buttons.DpadDown) ? 1 : 0, moveDown); - mapper.on(({gamepads}) => getLeftStickY(gamepads.at(0)) > 0 ? Math.abs(getLeftStickY(gamepads.at(0))) : 0, moveDown); - mapper.on(({keyboard, pointers}) => keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.y > actor.pos.y ? 1 : 0, moveDown); -} + mapper.on(({ keyboard }) => (keyboard.isHeld(ex.Keys.Down) ? 1 : 0), moveDown); + mapper.on(({ gamepads }) => (gamepads.at(0).getButton(ex.Buttons.DpadDown) ? 1 : 0), moveDown); + mapper.on(({ gamepads }) => (getLeftStickY(gamepads.at(0)) > 0 ? Math.abs(getLeftStickY(gamepads.at(0))) : 0), moveDown); + mapper.on( + ({ keyboard, pointers }) => (keyboard.isHeld(ex.Keys.Enter) && pointers.primary.lastWorldPos.y > actor.pos.y ? 1 : 0), + moveDown + ); +}; game.onPostUpdate = () => { actor.vel = ex.vec(0, 0); -} +}; game.currentScene.add(actor); -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/input/gamepad.html b/sandbox/tests/input/gamepad.html index 8de6dbd9..52af26d9 100644 --- a/sandbox/tests/input/gamepad.html +++ b/sandbox/tests/input/gamepad.html @@ -1,27 +1,27 @@ - + - - Gamepad Sample + + Gamepad Sample - - + + - +
-
Number of Gamepads
-
0
+
Number of Gamepads
+
0
- + diff --git a/sandbox/tests/input/gamepad.ts b/sandbox/tests/input/gamepad.ts index 52441f06..c26b4dd1 100644 --- a/sandbox/tests/input/gamepad.ts +++ b/sandbox/tests/input/gamepad.ts @@ -27,7 +27,7 @@ function start() { }); // Draw gamepad - var gamepad = new ex.Actor({width: padSprite.width, height: padSprite.height}); + var gamepad = new ex.Actor({ width: padSprite.width, height: padSprite.height }); gamepad.anchor.setTo(0, 0); gamepad.graphics.add(padSprite); game.add(gamepad); @@ -56,13 +56,13 @@ function start() { var buttonDef; for (var b = 0; b < buttonDefs.length; b++) { buttonDef = buttonDefs[b]; - buttons[b] = new CircleActor({x: buttonDef[1], y: buttonDef[2], width: 10, height: 10, color: new ex.Color(0, 0, 0, 0.7)}); + buttons[b] = new CircleActor({ x: buttonDef[1], y: buttonDef[2], width: 10, height: 10, color: new ex.Color(0, 0, 0, 0.7) }); game.add(buttons[b]); } // Sticks - var leftStick = new CircleActor({x: 330, y: 272, width: 25, height: 25, color: ex.Color.fromRGB(95, 164, 22, 0.6)}); - var rightStick = new CircleActor({x: 470, y: 272, width: 25, height: 25, color: ex.Color.fromRGB(164, 45, 22, 0.6)}); + var leftStick = new CircleActor({ x: 330, y: 272, width: 25, height: 25, color: ex.Color.fromRGB(95, 164, 22, 0.6) }); + var rightStick = new CircleActor({ x: 470, y: 272, width: 25, height: 25, color: ex.Color.fromRGB(164, 45, 22, 0.6) }); game.add(leftStick); game.add(rightStick); @@ -91,12 +91,10 @@ function start() { const actor = buttons[btn]; if (pad1.wasButtonPressed(btnIndex, 0.1) || pad1.wasButtonReleased(btnIndex)) { - actor.actions.clearActions() - actor.actions - .scaleTo(ex.Vector.One.scale(1.25), ex.Vector.One.scale(5)) - .scaleTo(ex.Vector.One.scale(1), ex.Vector.One.scale(5)) + actor.actions.clearActions(); + actor.actions.scaleTo(ex.Vector.One.scale(1.25), ex.Vector.One.scale(5)).scaleTo(ex.Vector.One.scale(1), ex.Vector.One.scale(5)); } - + if (pad1.isButtonPressed(btnIndex, 0.1)) { actor.color = new ex.Color(255, 0, 0, 0.8); actor.value = pad1.getButton(btnIndex); @@ -119,14 +117,16 @@ class CircleActor extends ex.Actor { this._text.text = this._value.toString(); } private _text = new ex.Text({ - text: this.value.toString(), + text: this.value.toString() }); constructor(args: ex.ActorArgs) { super(args); - this.graphics.add(new ex.Circle({ - radius: this.width, - color: this.color - })); + this.graphics.add( + new ex.Circle({ + radius: this.width, + color: this.color + }) + ); this.graphics.add(this._text); this._text.color = this.color; } diff --git a/sandbox/tests/input/iframe.html b/sandbox/tests/input/iframe.html index 8ac9c2d0..2601be92 100644 --- a/sandbox/tests/input/iframe.html +++ b/sandbox/tests/input/iframe.html @@ -1,4 +1,4 @@ - + diff --git a/sandbox/tests/input/iframe.ts b/sandbox/tests/input/iframe.ts index 7f7193f0..1ee39309 100644 --- a/sandbox/tests/input/iframe.ts +++ b/sandbox/tests/input/iframe.ts @@ -1,7 +1,7 @@ /// var game = new ex.Engine({ width: 800, height: 600, canvasElementId: 'game' }); -var label = new ex.Label({text: '', x: 400, y: 300, font: new ex.Font({size: 48, family: 'Arial'})}); +var label = new ex.Label({ text: '', x: 400, y: 300, font: new ex.Font({ size: 48, family: 'Arial' }) }); label.color = ex.Color.Chartreuse; label.font.textAlign = ex.TextAlign.Center; diff --git a/sandbox/tests/input/index.html b/sandbox/tests/input/index.html index 1f9b9409..65edef23 100644 --- a/sandbox/tests/input/index.html +++ b/sandbox/tests/input/index.html @@ -1,27 +1,27 @@ - + - - Input Sample + + Input Sample - - + + - +
-
Instructions
-
Move box around with arrow keys, gamepad D-pad, or gamepad left stick
+
Instructions
+
Move box around with arrow keys, gamepad D-pad, or gamepad left stick
- + diff --git a/sandbox/tests/input/index.ts b/sandbox/tests/input/index.ts index 02f2499c..fd42d04f 100644 --- a/sandbox/tests/input/index.ts +++ b/sandbox/tests/input/index.ts @@ -1,7 +1,7 @@ /// var game = new ex.Engine({ width: 500, height: 500, canvasElementId: 'game' }); -var box = new ex.Actor({x: 250, y: 250, width: 100, height: 100, color: ex.Color.Red}); +var box = new ex.Actor({ x: 250, y: 250, width: 100, height: 100, color: ex.Color.Red }); // Enable Gamepad support game.input.gamepads.enabled = true; diff --git a/sandbox/tests/input/innerframe.html b/sandbox/tests/input/innerframe.html index 10607d76..b32b2763 100644 --- a/sandbox/tests/input/innerframe.html +++ b/sandbox/tests/input/innerframe.html @@ -1,4 +1,4 @@ - + diff --git a/sandbox/tests/input/keyboard.html b/sandbox/tests/input/keyboard.html index 07866b91..33a77eb0 100644 --- a/sandbox/tests/input/keyboard.html +++ b/sandbox/tests/input/keyboard.html @@ -1,22 +1,22 @@ - + - - Keyboard Sample + + Keyboard Sample - - + + - + - + diff --git a/sandbox/tests/input/keyboard.ts b/sandbox/tests/input/keyboard.ts index 6cf47bed..d2e7dd47 100644 --- a/sandbox/tests/input/keyboard.ts +++ b/sandbox/tests/input/keyboard.ts @@ -1,17 +1,17 @@ /// var game = new ex.Engine({ width: 800, height: 600, canvasElementId: 'game' }); -var label = new ex.Label({text: '', x: 400, y: 300, font: new ex.Font({size: 48, family: 'Arial'})}); +var label = new ex.Label({ text: '', x: 400, y: 300, font: new ex.Font({ size: 48, family: 'Arial' }) }); label.color = ex.Color.Chartreuse; label.font.textAlign = ex.TextAlign.Center; game.add(label); -game.input.keyboard.on('press', e => { +game.input.keyboard.on('press', (e) => { console.log('Key Pressed:', e.key); }); -game.input.keyboard.on('release', e => { +game.input.keyboard.on('release', (e) => { console.log('Key Released:', e.key); }); @@ -26,7 +26,7 @@ game.on('postupdate', (ue: ex.PostUpdateEvent) => { label.text = keys; if (game.input.keyboard.wasPressed(ex.Keys.Enter)) { - console.log("Enter Pressed"); + console.log('Enter Pressed'); } }); diff --git a/sandbox/tests/input/pointer.html b/sandbox/tests/input/pointer.html index 8eb800bc..2370fad7 100644 --- a/sandbox/tests/input/pointer.html +++ b/sandbox/tests/input/pointer.html @@ -1,37 +1,37 @@ - + - - Pointer Sample + + Pointer Sample - - + + - +
-
Number of Pointers
-
0
-
Pointer (Primary) Button
-
None
-
Last Pointer Page Pos (x,y)
-
-
Last Pointer Screen Pos (x,y)
-
-
Last Pointer World Pos (x,y)
-
-
Last Wheel Deltas (x,y,z,mode)
-
+
Number of Pointers
+
0
+
Pointer (Primary) Button
+
None
+
Last Pointer Page Pos (x,y)
+
+
Last Pointer Screen Pos (x,y)
+
+
Last Pointer World Pos (x,y)
+
+
Last Wheel Deltas (x,y,z,mode)
+
- + diff --git a/sandbox/tests/input/pointer.ts b/sandbox/tests/input/pointer.ts index dc3baa7b..99cc5c9e 100644 --- a/sandbox/tests/input/pointer.ts +++ b/sandbox/tests/input/pointer.ts @@ -6,12 +6,12 @@ var game = new ex.Engine({ canvasElementId: 'game', pointerScope: ex.PointerScope.Document }); -var box = new ex.Actor({x: 200, y: 200, width: 100, height: 100, color: ex.Color.Red}); -var box2 = new ex.Actor({x: 0, y: 0, width: 50, height: 50, color: ex.Color.White}); -var cursor = new ex.Actor({x: 0, y: 0, width: 10, height: 10, color: ex.Color.Chartreuse}); +var box = new ex.Actor({ x: 200, y: 200, width: 100, height: 100, color: ex.Color.Red }); +var box2 = new ex.Actor({ x: 0, y: 0, width: 50, height: 50, color: ex.Color.White }); +var cursor = new ex.Actor({ x: 0, y: 0, width: 10, height: 10, color: ex.Color.Chartreuse }); var boxPointerDragging = false; -var uiElement = new ex.ScreenElement({x: 200, y: 0, width: 200, height: 200}); +var uiElement = new ex.ScreenElement({ x: 200, y: 0, width: 200, height: 200 }); uiElement.color = ex.Color.Azure; uiElement.on('pointerdown', (p: ex.PointerEvent) => { console.log(p); @@ -99,7 +99,7 @@ game.input.pointers.primary.on('wheel', (pe: ex.WheelEvent) => { var paintBrush = { paint: (x: number, y: number, color: ex.Color) => { - var brush = new ex.Actor({x, y, width: 5, height: 5, color}); + var brush = new ex.Actor({ x, y, width: 5, height: 5, color }); game.add(brush); } diff --git a/sandbox/tests/isometric/index.html b/sandbox/tests/isometric/index.html index 88ca8599..dcd4a1a2 100644 --- a/sandbox/tests/isometric/index.html +++ b/sandbox/tests/isometric/index.html @@ -1,13 +1,13 @@ - + - - - - - Isometric Map - - - - - - \ No newline at end of file + + + + + Isometric Map + + + + + + diff --git a/sandbox/tests/isometric/index.ts b/sandbox/tests/isometric/index.ts index ad8250ea..dd3b0714 100644 --- a/sandbox/tests/isometric/index.ts +++ b/sandbox/tests/isometric/index.ts @@ -27,7 +27,7 @@ var isoMap = new ex.IsometricMap({ columns: 3, rows: 3 }); -isoMap.tiles.forEach(t => t.addGraphic(isoSprite)); +isoMap.tiles.forEach((t) => t.addGraphic(isoSprite)); game.currentScene.add(isoMap); var isoMap2 = new ex.IsometricMap({ @@ -38,7 +38,7 @@ var isoMap2 = new ex.IsometricMap({ columns: 3, rows: 3 }); -isoMap2.tiles.forEach(t => t.addGraphic(isoTileSprite)); +isoMap2.tiles.forEach((t) => t.addGraphic(isoTileSprite)); game.currentScene.add(isoMap2); for (const tile of isoMap2.tiles) { tile.on('pointerdown', (evt: ex.PointerEvent) => { @@ -47,7 +47,7 @@ for (const tile of isoMap2.tiles) { } var tileCoord = ex.vec(0, 0); -game.input.pointers.on('move', evt => { +game.input.pointers.on('move', (evt) => { tileCoord = isoMap2.worldToTile(evt.worldPos); }); @@ -55,5 +55,4 @@ game.currentScene.on('postdraw', () => { game.graphicsContext.debug.drawText(`Current Coord: ${ex.vec(~~tileCoord.x, ~~tileCoord.y).toString()}`, ex.vec(700, 40)); }); - -game.start(loader); \ No newline at end of file +game.start(loader); diff --git a/sandbox/tests/kill/kill.html b/sandbox/tests/kill/kill.html index e664ee25..c80e66bf 100644 --- a/sandbox/tests/kill/kill.html +++ b/sandbox/tests/kill/kill.html @@ -1,16 +1,16 @@ - + - - - - - Kill test - - - -
- Actors should be removed when they collide with top - - - - \ No newline at end of file + + + + + Kill test + + + +
+ Actors should be removed when they collide with top + + + + diff --git a/sandbox/tests/label/fonts.html b/sandbox/tests/label/fonts.html index 5365ba71..6db268fb 100644 --- a/sandbox/tests/label/fonts.html +++ b/sandbox/tests/label/fonts.html @@ -1,13 +1,12 @@ - + - + Label Font Sample - - - + + - + diff --git a/sandbox/tests/label/fonts.ts b/sandbox/tests/label/fonts.ts index f486ef04..4968c3f9 100644 --- a/sandbox/tests/label/fonts.ts +++ b/sandbox/tests/label/fonts.ts @@ -2,12 +2,12 @@ var game = new ex.Engine({ width: 800, height: 300, canvasElementId: 'game' }); -var label = new ex.Label({text: 'Should be 72px Impact', x: 20, y: 100}); +var label = new ex.Label({ text: 'Should be 72px Impact', x: 20, y: 100 }); label.font.size = 72; label.font.family = 'Impact'; label.color = ex.Color.White; -var label2 = new ex.Label({text: 'Should be 20px Tahoma', x: 20, y: 150}); +var label2 = new ex.Label({ text: 'Should be 20px Tahoma', x: 20, y: 150 }); label2.font.size = 20; label2.font.family = 'Tahoma'; label2.color = ex.Color.Azure; diff --git a/sandbox/tests/label/label.html b/sandbox/tests/label/label.html index a5f8d31f..3944ac57 100644 --- a/sandbox/tests/label/label.html +++ b/sandbox/tests/label/label.html @@ -1,12 +1,12 @@ - + - + - - - -

The label text should be white, 20px consolas.

- - - + + + +

The label text should be white, 20px consolas.

+ + + diff --git a/sandbox/tests/label/label.ts b/sandbox/tests/label/label.ts index b6b12aca..baf2215b 100644 --- a/sandbox/tests/label/label.ts +++ b/sandbox/tests/label/label.ts @@ -1,13 +1,12 @@ /// - var engine = new ex.Engine({ canvasElementId: 'game', width: 600, height: 400 }); -var label = new ex.Label({text: 'This font should be white 20px consolas', x: 50, y: 50}); +var label = new ex.Label({ text: 'This font should be white 20px consolas', x: 50, y: 50 }); /*label.onInitialize = function() { label.color = ex.Color.White; }*/ @@ -16,7 +15,7 @@ label.font.family = 'Consolas'; label.font.unit = ex.FontUnit.Px; label.font.size = 20; -var label2 = new ex.Label({text: 'Should be azure 20px Tahoma', x: 20, y: 150, font: new ex.Font({size: 12, family: 'Arial'})}); +var label2 = new ex.Label({ text: 'Should be azure 20px Tahoma', x: 20, y: 150, font: new ex.Font({ size: 12, family: 'Arial' }) }); label2.font.family = 'Tahoma'; label2.font.unit = ex.FontUnit.Px; label2.font.size = 20; diff --git a/sandbox/tests/linebounds/index.html b/sandbox/tests/linebounds/index.html index 97ac7263..dead1214 100644 --- a/sandbox/tests/linebounds/index.html +++ b/sandbox/tests/linebounds/index.html @@ -1,13 +1,13 @@ - + - - - - Line Bounds - - - - - - - \ No newline at end of file + + + + Line Bounds + + + + + + + diff --git a/sandbox/tests/linebounds/index.ts b/sandbox/tests/linebounds/index.ts index ee03909b..ebcfc9f8 100644 --- a/sandbox/tests/linebounds/index.ts +++ b/sandbox/tests/linebounds/index.ts @@ -1,12 +1,12 @@ var game = new ex.Engine({ width: 1200, height: 400, - canvasElementId: "game", + canvasElementId: 'game', pixelRatio: 1 }); game.debug.entity.showName = true; -game.toggleDebug() +game.toggleDebug(); var actor = new ex.Actor({ pos: new ex.Vector(100, 100), @@ -31,18 +31,16 @@ class Beam extends ex.Actor { // longLine.height = 26; console.log(longLine.width, longLine.height); console.log(this.graphics.localBounds); - + this.graphics.use(longLine); } - onPreUpdate() { - - } + onPreUpdate() {} } var shortBeam = new Beam( { - name: "shortBeam", + name: 'shortBeam', pos: new ex.Vector(200, 200) }, 100 @@ -50,7 +48,7 @@ var shortBeam = new Beam( var longBeam = new Beam( { - name: "longBeam", + name: 'longBeam', pos: new ex.Vector(200, 300) }, 1001 diff --git a/sandbox/tests/many-colliders/index.html b/sandbox/tests/many-colliders/index.html index a87882f1..da7c11ba 100644 --- a/sandbox/tests/many-colliders/index.html +++ b/sandbox/tests/many-colliders/index.html @@ -1,13 +1,13 @@ - + - - - - - Many colliders performance test - - - - - - \ No newline at end of file + + + + + Many colliders performance test + + + + + + diff --git a/sandbox/tests/many-colliders/index.ts b/sandbox/tests/many-colliders/index.ts index bbafae37..a2b4823c 100644 --- a/sandbox/tests/many-colliders/index.ts +++ b/sandbox/tests/many-colliders/index.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 800, height: 600 @@ -9,16 +8,13 @@ var random = new ex.Random(1337); for (let i = 0; i < 500; i++) { (() => { let actor = new ex.Actor({ - x: ex.randomInRange(0, 800, random), + x: ex.randomInRange(0, 800, random), y: ex.randomIntInRange(0, 600, random), vel: ex.vec(ex.randomInRange(-50, 50, random), ex.randomInRange(-50, 50, random)), collisionType: ex.CollisionType.Active, width: 20, height: 20, - color: ex.Color.fromRGB( - ex.randomIntInRange(0, 255, random), - ex.randomIntInRange(0, 255, random), - ex.randomIntInRange(0, 255, random)) + color: ex.Color.fromRGB(ex.randomIntInRange(0, 255, random), ex.randomIntInRange(0, 255, random), ex.randomIntInRange(0, 255, random)) }); actor.onPostUpdate = () => { if (actor.pos.x > 800) { @@ -38,5 +34,4 @@ for (let i = 0; i < 500; i++) { })(); } - -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/material/index.html b/sandbox/tests/material/index.html index 33c097e4..771a7e56 100644 --- a/sandbox/tests/material/index.html +++ b/sandbox/tests/material/index.html @@ -1,13 +1,13 @@ - + - - - - Material - - - - - - - \ No newline at end of file + + + + Material + + + + + + + diff --git a/sandbox/tests/material/index.ts b/sandbox/tests/material/index.ts index 7254a0e8..f5eba73d 100644 --- a/sandbox/tests/material/index.ts +++ b/sandbox/tests/material/index.ts @@ -1,7 +1,7 @@ /// // identity tagged template literal lights up glsl-literal vscode plugin -var glsl = x => x[0]; +var glsl = (x) => x[0]; var game = new ex.Engine({ canvasElementId: 'game', @@ -57,7 +57,7 @@ void main() { float factor = smoothstep(0.5, 0.7, mat.a); fragColor = mix(fragColor, mat, factor); } -` +`; var fragmentSource = glsl`#version 300 es precision mediump float; @@ -101,25 +101,23 @@ void main() { fragColor = color * u_color; } -` +`; var swirlMaterial = game.graphicsContext.createMaterial({ name: 'swirl', fragmentSource }); - - var click = ex.vec(0, 0); -game.input.pointers.primary.on('down', evt => { +game.input.pointers.primary.on('down', (evt) => { click = evt.worldPos; // might need to change if you have a camera }); var outlineMaterial = game.graphicsContext.createMaterial({ name: 'outline', fragmentSource: outline -}) +}); var actor = new ex.Actor({ x: 100, y: 100, width: 50, height: 50 }); actor.onInitialize = () => { @@ -140,18 +138,17 @@ heartActor.onInitialize = () => { sprite.scale = ex.vec(4, 4); heartActor.graphics.add(sprite); heartActor.graphics.material = outlineMaterial; -} +}; game.add(heartActor); -game.input.pointers.primary.on('move', evt => { +game.input.pointers.primary.on('move', (evt) => { heartActor.pos = evt.worldPos; - swirlMaterial.update(shader => { + swirlMaterial.update((shader) => { shader.trySetUniformFloatVector('iMouse', evt.worldPos); }); }); - var backgroundActor = new ex.ScreenElement({ x: 0, y: 0, width: 512, height: 512, z: -1 }); backgroundActor.onInitialize = () => { @@ -159,7 +156,6 @@ backgroundActor.onInitialize = () => { backgroundActor.graphics.material = swirlMaterial; }; - // material without graphic!? var waterFrag = glsl`#version 300 es precision mediump float; @@ -275,17 +271,17 @@ loader.addResource(noise); var waterMaterial = game.graphicsContext.createMaterial({ name: 'water', fragmentSource: waterFrag, - color: ex.Color.fromRGB(55, 0, 200, .6), + color: ex.Color.fromRGB(55, 0, 200, 0.6), images: { u_noise: noise } }); var reflection = new ex.Actor({ x: 0, - y: game.screen.resolution.height/2, + y: game.screen.resolution.height / 2, anchor: ex.vec(0, 0), width: 512, - height: game.screen.resolution.height/2, + height: game.screen.resolution.height / 2, coordPlane: ex.CoordPlane.Screen, color: ex.Color.Red }); @@ -297,8 +293,7 @@ game.add(actor); game.add(backgroundActor); game.add(reflection); - game.start(loader).then(async () => { // const image = await game.screenshot(true); // document.body.appendChild(image); -}); \ No newline at end of file +}); diff --git a/sandbox/tests/multi-engine/index.html b/sandbox/tests/multi-engine/index.html index 2c700d89..f020dac3 100644 --- a/sandbox/tests/multi-engine/index.html +++ b/sandbox/tests/multi-engine/index.html @@ -1,15 +1,15 @@ - + - - - - - Document - - - - - - - - \ No newline at end of file + + + + + Document + + + + + + + + diff --git a/sandbox/tests/multi-engine/index.ts b/sandbox/tests/multi-engine/index.ts index 36ad2273..432dfe9f 100644 --- a/sandbox/tests/multi-engine/index.ts +++ b/sandbox/tests/multi-engine/index.ts @@ -1,17 +1,18 @@ - var engine1 = new ex.Engine({ canvasElementId: 'game1', width: 600, height: 400, backgroundColor: ex.Color.Black }); -engine1.add(new ex.Actor({ - color: ex.Color.Blue, - x: 100, - y: 100, - width: 100, - height: 100, -})); +engine1.add( + new ex.Actor({ + color: ex.Color.Blue, + x: 100, + y: 100, + width: 100, + height: 100 + }) +); engine1.start(); var engine2 = new ex.Engine({ @@ -20,11 +21,13 @@ var engine2 = new ex.Engine({ height: 400, backgroundColor: ex.Color.ExcaliburBlue }); -engine2.add(new ex.Actor({ - color: ex.Color.Red, - x: 100, - y: 100, - width: 100, - height: 100, -})); -engine2.start(); \ No newline at end of file +engine2.add( + new ex.Actor({ + color: ex.Color.Red, + x: 100, + y: 100, + width: 100, + height: 100 + }) +); +engine2.start(); diff --git a/sandbox/tests/opacity/index.html b/sandbox/tests/opacity/index.html index f8aaf844..c8052b08 100644 --- a/sandbox/tests/opacity/index.html +++ b/sandbox/tests/opacity/index.html @@ -1,13 +1,12 @@ - + - + Opacity Test - - + +

After 1 second, a red square and a red heart should appear

- - - \ No newline at end of file + + diff --git a/sandbox/tests/opacity/opacity.ts b/sandbox/tests/opacity/opacity.ts index d2afe98c..c63ae036 100644 --- a/sandbox/tests/opacity/opacity.ts +++ b/sandbox/tests/opacity/opacity.ts @@ -5,8 +5,8 @@ var hrt = new ex.ImageSource('../../images/heart.png'); var ldr = new ex.Loader([hrt]); game.start(ldr).then(() => { - var a = new ex.Actor({x: 50, y: 50, width: 50, height: 50, color: ex.Color.Red}); - var b = new ex.Actor({x: 150, y: 50, width: 50, height: 50}); + var a = new ex.Actor({ x: 50, y: 50, width: 50, height: 50, color: ex.Color.Red }); + var b = new ex.Actor({ x: 150, y: 50, width: 50, height: 50 }); b.graphics.add(hrt.toSprite()); b.graphics.opacity = 0; diff --git a/sandbox/tests/parallax/index.html b/sandbox/tests/parallax/index.html index f3c7858d..fe7f1714 100644 --- a/sandbox/tests/parallax/index.html +++ b/sandbox/tests/parallax/index.html @@ -1,13 +1,13 @@ - + - - - - - Parallax - - - - - - \ No newline at end of file + + + + + Parallax + + + + + + diff --git a/sandbox/tests/parallax/index.ts b/sandbox/tests/parallax/index.ts index 84bd2192..399544b7 100644 --- a/sandbox/tests/parallax/index.ts +++ b/sandbox/tests/parallax/index.ts @@ -16,12 +16,12 @@ var tilemap = new ex.TileMap({ rows: 4, columns: 4 }); -tilemap.tiles.forEach(t => { +tilemap.tiles.forEach((t) => { t.addGraphic(graphic); }); tilemap.addComponent(new ex.ParallaxComponent(ex.vec(0.5, 0.5))); -game.input.keyboard.on("press", event => { +game.input.keyboard.on('press', (event) => { if (event.key === ex.Keys.ArrowUp) { game.currentScene.camera.pos.y -= 10; } @@ -30,13 +30,15 @@ game.input.keyboard.on("press", event => { } }); -game.add(new ex.Actor({ - width: 100, - height: 100, - color: ex.Color.Red, - z: 10 -})); +game.add( + new ex.Actor({ + width: 100, + height: 100, + color: ex.Color.Red, + z: 10 + }) +); game.add(tilemap); -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/parallel/index.html b/sandbox/tests/parallel/index.html index f3c7858d..fe7f1714 100644 --- a/sandbox/tests/parallel/index.html +++ b/sandbox/tests/parallel/index.html @@ -1,13 +1,13 @@ - + - - - - - Parallax - - - - - - \ No newline at end of file + + + + + Parallax + + + + + + diff --git a/sandbox/tests/parallel/index.ts b/sandbox/tests/parallel/index.ts index d91ae1ce..0c3833da 100644 --- a/sandbox/tests/parallel/index.ts +++ b/sandbox/tests/parallel/index.ts @@ -1,5 +1,3 @@ - - var game = new ex.Engine({ width: 800, height: 600, @@ -17,7 +15,6 @@ var actor = new ex.Actor({ actor.graphics.use(image.toSprite()); // game.add(actor); - class MyActor extends ex.Actor { constructor() { super({ @@ -30,12 +27,12 @@ class MyActor extends ex.Actor { } async takeDamage(): Promise { - const knockBackSequence = new ex.ActionSequence(this, ctx => { - ctx.moveBy(ex.vec(100, 0), 500) - ctx.moveBy(ex.vec(-100, 0), 500) + const knockBackSequence = new ex.ActionSequence(this, (ctx) => { + ctx.moveBy(ex.vec(100, 0), 500); + ctx.moveBy(ex.vec(-100, 0), 500); }); - - const fadeSequence = new ex.ActionSequence(this, ctx => { + + const fadeSequence = new ex.ActionSequence(this, (ctx) => { ctx.delay(100); ctx.fade(0, 1000); }); @@ -48,8 +45,7 @@ var myActor = new MyActor(); game.add(myActor); myActor.takeDamage(); - -var sequence1 = new ex.ActionSequence(actor, ctx => { +var sequence1 = new ex.ActionSequence(actor, (ctx) => { ctx.easeBy(ex.vec(200, 0), 1000, ex.EasingFunctions.EaseInOutCubic); ctx.delay(500); ctx.easeBy(ex.vec(0, 200), 1000, ex.EasingFunctions.EaseInOutCubic); @@ -60,7 +56,7 @@ var sequence1 = new ex.ActionSequence(actor, ctx => { ctx.delay(500); }); -var sequence2 = new ex.ActionSequence(actor, ctx => { +var sequence2 = new ex.ActionSequence(actor, (ctx) => { ctx.rotateBy(Math.PI, Math.PI, ex.RotationType.Clockwise); ctx.delay(500); ctx.rotateBy(Math.PI, Math.PI, ex.RotationType.CounterClockwise); @@ -71,14 +67,14 @@ var sequence2 = new ex.ActionSequence(actor, ctx => { ctx.delay(500); }); -var sequence3 = new ex.ActionSequence(actor, ctx => { +var sequence3 = new ex.ActionSequence(actor, (ctx) => { ctx.scaleBy(ex.vec(2, 2), 1); ctx.delay(1000); ctx.scaleBy(ex.vec(-2, -2), 1); ctx.delay(1000); }); -var sequence4 = new ex.ActionSequence(actor, ctx => { +var sequence4 = new ex.ActionSequence(actor, (ctx) => { ctx.fade(0, 2000); ctx.delay(1000); ctx.fade(1, 2000); @@ -89,8 +85,7 @@ var blink = new ex.Blink(actor, 200, 200, 2); var spawn = new ex.ParallelActions([sequence1, sequence2, sequence3, sequence4, blink]); -actor.actions.repeatForever(ctx => ctx.runAction(spawn)); +actor.actions.repeatForever((ctx) => ctx.runAction(spawn)); game.currentScene.camera.pos = ex.Vector.Zero; - -game.start(loader); \ No newline at end of file +game.start(loader); diff --git a/sandbox/tests/physics/fastphysics.html b/sandbox/tests/physics/fastphysics.html index d82da935..c0a587be 100644 --- a/sandbox/tests/physics/fastphysics.html +++ b/sandbox/tests/physics/fastphysics.html @@ -1,13 +1,13 @@ - + - - + +

Press arrow keys to launch in different directions for more rockets

Rockets should not leave their confines

Compare with ex.Physics.checkForFastBodies = false

- + diff --git a/sandbox/tests/physics/fastphysics.ts b/sandbox/tests/physics/fastphysics.ts index 21ed337b..684c564c 100644 --- a/sandbox/tests/physics/fastphysics.ts +++ b/sandbox/tests/physics/fastphysics.ts @@ -1,6 +1,6 @@ /// -ex.Physics.useRealisticPhysics() +ex.Physics.useRealisticPhysics(); var game = new ex.Engine({ width: 600, height: 400 @@ -19,7 +19,7 @@ var rocketTex = new ex.ImageSource('missile.png'); var loader = new ex.Loader([rocketTex]); function spawnRocket(direction) { - var rocket = new ex.Actor({x: 300, y: 200, radius: 48, height: 16}); + var rocket = new ex.Actor({ x: 300, y: 200, radius: 48, height: 16 }); rocket.body.canSleep = true; rocket.on('preupdate', () => { @@ -56,23 +56,23 @@ function spawnRocket(direction) { game.add(rocket); } -var ground = new ex.Actor({x: 0, y: 400, width: 5, height: 5, color: ex.Color.Black.clone()}); +var ground = new ex.Actor({ x: 0, y: 400, width: 5, height: 5, color: ex.Color.Black.clone() }); ground.body.collisionType = ex.CollisionType.Fixed; ground.collider.useEdgeCollider(new ex.Vector(0, 0), new ex.Vector(600, 0)); // ground.collider.useBoxCollider(600, 30, ex.Vector.Zero); game.add(ground); -var rightWall = new ex.Actor({x: 600, y: 200, width: 10, height: 400, color: ex.Color.Black.clone()}); +var rightWall = new ex.Actor({ x: 600, y: 200, width: 10, height: 400, color: ex.Color.Black.clone() }); rightWall.body.collisionType = ex.CollisionType.Fixed; rightWall.collider.useBoxCollider(10, 400); game.add(rightWall); -var leftWall = new ex.Actor({x: 0, y: 200, width: 10, height: 400, color: ex.Color.Black.clone()}); +var leftWall = new ex.Actor({ x: 0, y: 200, width: 10, height: 400, color: ex.Color.Black.clone() }); leftWall.body.collisionType = ex.CollisionType.Fixed; leftWall.collider.useBoxCollider(10, 400); game.add(leftWall); -var ceiling = new ex.Actor({x: 300, y: 10, width: 600, height: 10, color: ex.Color.Blue.clone()}); +var ceiling = new ex.Actor({ x: 300, y: 10, width: 600, height: 10, color: ex.Color.Blue.clone() }); ceiling.body.collisionType = ex.CollisionType.Fixed; ceiling.collider.useBoxCollider(600, 10); // optional game.add(ceiling); diff --git a/sandbox/tests/physics/index.html b/sandbox/tests/physics/index.html index a38f23c6..d2cd7011 100644 --- a/sandbox/tests/physics/index.html +++ b/sandbox/tests/physics/index.html @@ -1,14 +1,16 @@ - + - - + +

Press b for more blocks

-

Press c for more circles

- - - - - +

Press c for more circles

+

+ + + + +

+ diff --git a/sandbox/tests/physics/physics.ts b/sandbox/tests/physics/physics.ts index 93074051..332f0d7c 100644 --- a/sandbox/tests/physics/physics.ts +++ b/sandbox/tests/physics/physics.ts @@ -19,8 +19,6 @@ ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; ex.Physics.bodiesCanSleepByDefault = true; ex.Physics.gravity = ex.vec(0, 100); - - var globalRotation = 0; function spawnBlock(x: number, y: number) { var width = ex.randomInRange(20, 100); @@ -57,7 +55,7 @@ function spawnBlock(x: number, y: number) { function spawnCircle(x: number, y: number) { var width = ex.randomInRange(20, 100); var color = new ex.Color(255, ex.randomIntInRange(0, 255), ex.randomIntInRange(0, 255)); - var circle = new ex.Actor({x: x, y: y, radius: width / 2, color: color}); + var circle = new ex.Actor({ x: x, y: y, radius: width / 2, color: color }); // circle.rx = ex.Util.randomInRange(-0.5, 0.5); // circle.angularVelocity = 1; // circle.vel.setTo(0, 300); @@ -79,9 +77,9 @@ function spawnCircle(x: number, y: number) { var edge = new ex.Actor({ x: 200, - y:300, + y: 300, width: 5, - height: 5, + height: 5, color: ex.Color.Blue.clone() }); edge.body.collisionType = ex.CollisionType.Fixed; @@ -89,7 +87,6 @@ edge.collider.useEdgeCollider(new ex.Vector(0, 0), new ex.Vector(200, 0)); // // edge.rx = .4; game.add(edge); - // var solid = new ex.Actor(300, 380, 100, 100, ex.Color.Azure.clone()); // solid.body.collisionType = ex.CollisionType.Fixed; // // solid.body.rotation = Math.PI / 4; @@ -97,18 +94,18 @@ game.add(edge); // spawnBlock(300, 200).body.setSleeping(true); -var ground = new ex.Actor({x: 300, y: 380, width: 600, height: 10, color: ex.Color.Azure.clone()}); +var ground = new ex.Actor({ x: 300, y: 380, width: 600, height: 10, color: ex.Color.Azure.clone() }); ground.body.collisionType = ex.CollisionType.Fixed; ground.body.bounciness = 0.0; ground.collider.useBoxCollider(600, 10); // optional game.add(ground); -var leftWall = new ex.Actor({x: 0, y: 300, width: 10, height: 400, color: ex.Color.Azure.clone()}); +var leftWall = new ex.Actor({ x: 0, y: 300, width: 10, height: 400, color: ex.Color.Azure.clone() }); leftWall.body.collisionType = ex.CollisionType.Fixed; leftWall.collider.useBoxCollider(10, 400); game.add(leftWall); -var rightWall = new ex.Actor({x: 600, y: 300, width: 10, height: 400, color: ex.Color.Azure.clone()}); +var rightWall = new ex.Actor({ x: 600, y: 300, width: 10, height: 400, color: ex.Color.Azure.clone() }); rightWall.body.collisionType = ex.CollisionType.Fixed; rightWall.collider.useBoxCollider(10, 400); game.add(rightWall); @@ -134,4 +131,4 @@ game.input.pointers.primary.on('down', (evt: ex.PointerEvent) => { game.start(); //@ts-ignore -// const dev = new ex.DevTools.DevTool(game); \ No newline at end of file +// const dev = new ex.DevTools.DevTool(game); diff --git a/sandbox/tests/physics/physics2.html b/sandbox/tests/physics/physics2.html index 61f570cd..fe6e48a0 100644 --- a/sandbox/tests/physics/physics2.html +++ b/sandbox/tests/physics/physics2.html @@ -1,10 +1,10 @@ - + - - + + - - \ No newline at end of file + + diff --git a/sandbox/tests/physics/physics2.ts b/sandbox/tests/physics/physics2.ts index ff6c3168..c25ae935 100644 --- a/sandbox/tests/physics/physics2.ts +++ b/sandbox/tests/physics/physics2.ts @@ -17,7 +17,7 @@ game.currentScene.camera.zoomOverTime(3); function spawnCircle2(x: number, y: number, vx: number) { var width = 20; var color = new ex.Color(ex.randomIntInRange(0, 255), ex.randomIntInRange(0, 255), ex.randomIntInRange(0, 255)); - var circle = new ex.Actor({x, y, width, height: width, color}); + var circle = new ex.Actor({ x, y, width, height: width, color }); circle.vel.x = vx; circle.collider.useCircleCollider(width / 2); circle.body.collisionType = ex.CollisionType.Active; diff --git a/sandbox/tests/pointer/index.html b/sandbox/tests/pointer/index.html index 191c3310..ec159bfe 100644 --- a/sandbox/tests/pointer/index.html +++ b/sandbox/tests/pointer/index.html @@ -1,22 +1,24 @@ - + - - - - - Pointer - - - -

Click on the squares to see events propagate in z order in the console. The black square cancels the event preventing propagation.

- - - - \ No newline at end of file + + + +

+ Click on the squares to see events propagate in z order in the console. The black square cancels the event preventing propagation. +

+ + + + diff --git a/sandbox/tests/pointer/pointer.ts b/sandbox/tests/pointer/pointer.ts index 36ad46a9..13be9910 100644 --- a/sandbox/tests/pointer/pointer.ts +++ b/sandbox/tests/pointer/pointer.ts @@ -2,7 +2,7 @@ class Player extends ex.Actor { constructor(color: ex.Color, size = 100) { - super({x: 300, y: 200, width: size, height: size, color}); + super({ x: 300, y: 200, width: size, height: size, color }); } } @@ -18,41 +18,40 @@ class Game2 extends ex.Engine { screenElement.pointer.useColliderShape = true; screenElement.pointer.useGraphicsBounds = true; screenElement.on('pointerdown', () => { - console.log('screen element down') + console.log('screen element down'); }); screenElement.on('pointerup', () => { - console.log('screen element up') + console.log('screen element up'); }); this.add(screenElement); - const player1 = new Player(ex.Color.Green); this.add(player1); player1.z = 10; - player1.on("pointerdown", (e) => { - console.log("green"); + player1.on('pointerdown', (e) => { + console.log('green'); }); const player2 = new Player(ex.Color.Blue); this.add(player2); player2.rotation = 0.3; player2.z = 5; - player2.on("pointerdown", (e) => { - console.log("blue"); + player2.on('pointerdown', (e) => { + console.log('blue'); }); const player3 = new Player(ex.Color.Rose); this.add(player3); player3.rotation = 0.6; player3.z = 1; - player3.on("pointerdown", (e) => { - console.log("rose"); + player3.on('pointerdown', (e) => { + console.log('rose'); }); const player4 = new Player(ex.Color.Black, 20); this.add(player4); player4.z = 11; - player4.on('pointerdown', e => { + player4.on('pointerdown', (e) => { console.log('black'); console.log('event canceled'); e.cancel(); @@ -85,4 +84,4 @@ game2.input.pointers.primary.on('down', (evt) => { document.body.appendChild(div); }); -game2.initialize(); \ No newline at end of file +game2.initialize(); diff --git a/sandbox/tests/polygon/index.html b/sandbox/tests/polygon/index.html index f96a40eb..10d14458 100644 --- a/sandbox/tests/polygon/index.html +++ b/sandbox/tests/polygon/index.html @@ -1,12 +1,12 @@ - + - - - - Polygon Triangulate - - - - - - \ No newline at end of file + + + + Polygon Triangulate + + + + + + diff --git a/sandbox/tests/polygon/index.ts b/sandbox/tests/polygon/index.ts index 496ed701..3990c34f 100644 --- a/sandbox/tests/polygon/index.ts +++ b/sandbox/tests/polygon/index.ts @@ -1,6 +1,5 @@ /// - var game = new ex.Engine({ width: 800, height: 600, @@ -9,7 +8,7 @@ var game = new ex.Engine({ game.toggleDebug(); game.debug.collider.showBounds = false; -var actor = new ex.Actor({pos: ex.vec(200, 100)}); +var actor = new ex.Actor({ pos: ex.vec(200, 100) }); // var shape = ex.Shape.Polygon([ // ex.vec(0,0), // ex.vec(-1.6875,-25.0625), @@ -57,33 +56,27 @@ var actor = new ex.Actor({pos: ex.vec(200, 100)}); // ex.vec(100,300)]; var points = [ - ex.vec(343,392), - ex.vec(475,103), - ex.vec(245,151), - ex.vec(193,323), + ex.vec(343, 392), + ex.vec(475, 103), + ex.vec(245, 151), + ex.vec(193, 323), ex.vec(91, 279), ex.vec(51, 301), ex.vec(25, 381), ex.vec(80, 334), - ex.vec(142,418), - ex.vec(325,480), - ex.vec(340,564), - ex.vec(468,597) -] - -var colinear = [ - ex.vec(160, 80), - ex.vec(80, 40), - ex.vec(0, 0), + ex.vec(142, 418), + ex.vec(325, 480), + ex.vec(340, 564), + ex.vec(468, 597) ]; +var colinear = [ex.vec(160, 80), ex.vec(80, 40), ex.vec(0, 0)]; + function triangleArea(a: ex.Vector, b: ex.Vector, c: ex.Vector) { - return Math.abs((a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y)))/2 + return Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y)) / 2; } -console.log('triangle area', triangleArea(ex.vec(160, 80), -ex.vec(80, 40), -ex.vec(0, 0))); +console.log('triangle area', triangleArea(ex.vec(160, 80), ex.vec(80, 40), ex.vec(0, 0))); var shape = ex.Shape.Polygon(points, ex.Vector.Zero, true); @@ -91,5 +84,5 @@ var triangulated = shape.triangulate(); actor.collider.set(triangulated); game.add(actor); -game.currentScene.camera.zoom = .75; -game.start(); \ No newline at end of file +game.currentScene.camera.zoom = 0.75; +game.start(); diff --git a/sandbox/tests/postprocessor/index.html b/sandbox/tests/postprocessor/index.html index 308c6b82..c789db0f 100644 --- a/sandbox/tests/postprocessor/index.html +++ b/sandbox/tests/postprocessor/index.html @@ -1,12 +1,12 @@ - + - - - - Post-processing - - - - - - \ No newline at end of file + + + + Post-processing + + + + + + diff --git a/sandbox/tests/postprocessor/main.ts b/sandbox/tests/postprocessor/main.ts index 5068aaa6..2c5a9216 100644 --- a/sandbox/tests/postprocessor/main.ts +++ b/sandbox/tests/postprocessor/main.ts @@ -67,7 +67,7 @@ void main() // col = mix( col, oricol, comp ); fragColor = vec4(col,1.0); -}` +}`; class CRTPostProcessors implements ex.PostProcessor { private _shader: ex.ScreenShader; @@ -99,17 +99,16 @@ var actor = new ex.Actor({ height: 100, color: ex.Color.Red }); -actor.angularVelocity = .2; -actor.actions - .repeatForever((ctx) => { - ctx.moveTo(ex.vec(600, 0), 200); - ctx.moveTo(ex.vec(0, 400), 200); - ctx.moveTo(ex.vec(600, 400), 200); - ctx.moveTo(ex.vec(0, 0), 200); - }); +actor.angularVelocity = 0.2; +actor.actions.repeatForever((ctx) => { + ctx.moveTo(ex.vec(600, 0), 200); + ctx.moveTo(ex.vec(0, 400), 200); + ctx.moveTo(ex.vec(600, 400), 200); + ctx.moveTo(ex.vec(0, 0), 200); +}); game.currentScene.add(actor); var ctx = game.graphicsContext as ex.ExcaliburGraphicsContextWebGL; ctx.addPostProcessor(new CRTPostProcessors()); -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/raycast/index.html b/sandbox/tests/raycast/index.html index 453486d4..a68398b4 100644 --- a/sandbox/tests/raycast/index.html +++ b/sandbox/tests/raycast/index.html @@ -1,12 +1,12 @@ - + - - - - Scene Raycasting - - - - - - \ No newline at end of file + + + + Scene Raycasting + + + + + + diff --git a/sandbox/tests/raycast/main.ts b/sandbox/tests/raycast/main.ts index 74e3502b..e322d29c 100644 --- a/sandbox/tests/raycast/main.ts +++ b/sandbox/tests/raycast/main.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 600, height: 400, @@ -28,11 +27,11 @@ player.onPostUpdate = (engine) => { player.vel = ex.Vector.Zero; const keyboard = engine.input.keyboard; if (keyboard.isHeld(ex.Keys.ArrowLeft)) { - playerDir = playerDir.rotate(-rotationAmount) + playerDir = playerDir.rotate(-rotationAmount); player.rotation -= rotationAmount; } - if (keyboard.isHeld(ex.Keys.ArrowRight)){ - playerDir = playerDir.rotate(+rotationAmount) + if (keyboard.isHeld(ex.Keys.ArrowRight)) { + playerDir = playerDir.rotate(+rotationAmount); player.rotation += rotationAmount; } if (keyboard.isHeld(ex.Keys.ArrowUp)) { @@ -40,24 +39,24 @@ player.onPostUpdate = (engine) => { } // raycast - var hits = engine.currentScene.physics.rayCast( - new ex.Ray(player.pos, playerDir), - { - maxDistance: playerSightDistance, - // collisionMask: notPlayers, - collisionGroup: notPlayers2, - searchAllColliders: false - }); + var hits = engine.currentScene.physics.rayCast(new ex.Ray(player.pos, playerDir), { + maxDistance: playerSightDistance, + // collisionMask: notPlayers, + collisionGroup: notPlayers2, + searchAllColliders: false + }); for (let hit of hits) { const hitActor = hit.collider.owner as ex.Actor; - hitActor.graphics.use(new ex.Rectangle({ - color: ex.Color.Violet, - width: 20, - height: 20 - })); + hitActor.graphics.use( + new ex.Rectangle({ + color: ex.Color.Violet, + width: 20, + height: 20 + }) + ); } -} +}; player.graphics.onPostDraw = (ctx) => { ctx.drawLine(ex.Vector.Zero, ex.Vector.Right.scale(playerSightDistance), ex.Color.Red, 2); }; @@ -77,4 +76,4 @@ for (let i = 0; i < 10; i++) { game.currentScene.add(block); } -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/rotation/rotation.html b/sandbox/tests/rotation/rotation.html index b0435d54..b5abf31b 100644 --- a/sandbox/tests/rotation/rotation.html +++ b/sandbox/tests/rotation/rotation.html @@ -1,13 +1,13 @@ - + - + Rotation Test - - + +

Press 'd' for debug mode

Click the buttons to change the RotationType. Click anywhere else on the canvas to have the actor rotate to that angle.

- - \ No newline at end of file + + diff --git a/sandbox/tests/rotation/rotation.ts b/sandbox/tests/rotation/rotation.ts index b51b644c..260f5d1c 100644 --- a/sandbox/tests/rotation/rotation.ts +++ b/sandbox/tests/rotation/rotation.ts @@ -15,7 +15,7 @@ var engine = new ex.Engine({ }); engine.backgroundColor = ex.Color.Black; -var labelCurrentRotation = new ex.Label({text: rotationType.toString(), x: 500, y: 100}); +var labelCurrentRotation = new ex.Label({ text: rotationType.toString(), x: 500, y: 100 }); labelCurrentRotation.color = ex.Color.White; labelCurrentRotation.font.textAlign = ex.TextAlign.Center; labelCurrentRotation.scale = new ex.Vector(2, 2); @@ -25,52 +25,52 @@ engine.on('postupdate', (ev: ex.PostUpdateEvent) => { labelCurrentRotation.text = ex.RotationType[rotationType]; }); -var player = new ex.Actor({x: width / 2, y: height / 2, width: 100, height: 30, color: ex.Color.Red}); +var player = new ex.Actor({ x: width / 2, y: height / 2, width: 100, height: 30, color: ex.Color.Red }); var playerSprite = playerTexture.toSprite(); player.graphics.add(playerSprite); engine.currentScene.add(player); // rotation type buttons -var shortestPath = new ex.Actor({x: 50, y: 50, width: 50, height: 50, color: ex.Color.White}); +var shortestPath = new ex.Actor({ x: 50, y: 50, width: 50, height: 50, color: ex.Color.White }); shortestPath.on('pointerdown', (e?: ex.PointerEvent) => { rotationType = ex.RotationType.ShortestPath; }); engine.add(shortestPath); -var labelShortestPath = new ex.Label({text: 'Shortest Path', x: shortestPath.pos.x, y: 100}); +var labelShortestPath = new ex.Label({ text: 'Shortest Path', x: shortestPath.pos.x, y: 100 }); labelShortestPath.color = ex.Color.White; labelShortestPath.font.textAlign = ex.TextAlign.Center; engine.add(labelShortestPath); -var longestPath = new ex.Actor({x: 150, y: 50, width: 50, height: 50, color: ex.Color.White}); +var longestPath = new ex.Actor({ x: 150, y: 50, width: 50, height: 50, color: ex.Color.White }); longestPath.on('pointerdown', (e?: ex.PointerEvent) => { rotationType = ex.RotationType.LongestPath; }); engine.add(longestPath); -var labelLongestPath = new ex.Label({text: 'Longest Path', x: longestPath.pos.x, y: 100}); +var labelLongestPath = new ex.Label({ text: 'Longest Path', x: longestPath.pos.x, y: 100 }); labelLongestPath.color = ex.Color.White; labelLongestPath.font.textAlign = ex.TextAlign.Center; engine.add(labelLongestPath); -var clockwise = new ex.Actor({x: 250, y: 50, width: 50, height: 50, color: ex.Color.White}); +var clockwise = new ex.Actor({ x: 250, y: 50, width: 50, height: 50, color: ex.Color.White }); clockwise.on('pointerdown', (e?: ex.PointerEvent) => { rotationType = ex.RotationType.Clockwise; }); engine.add(clockwise); -var labelClockwise = new ex.Label({text: 'Clockwise', x: clockwise.pos.x, y: 100}); +var labelClockwise = new ex.Label({ text: 'Clockwise', x: clockwise.pos.x, y: 100 }); labelClockwise.color = ex.Color.White; labelClockwise.font.textAlign = ex.TextAlign.Center; engine.add(labelClockwise); -var counterclockwise = new ex.Actor({x: 350, y: 50, width: 50, height: 50, color: ex.Color.White}); +var counterclockwise = new ex.Actor({ x: 350, y: 50, width: 50, height: 50, color: ex.Color.White }); counterclockwise.on('pointerdown', (e?: ex.PointerEvent) => { rotationType = ex.RotationType.CounterClockwise; }); engine.add(counterclockwise); -var labelCounterClockwise = new ex.Label({text: 'CounterClockwise', x: counterclockwise.pos.x, y: 100}); +var labelCounterClockwise = new ex.Label({ text: 'CounterClockwise', x: counterclockwise.pos.x, y: 100 }); labelCounterClockwise.color = ex.Color.White; labelCounterClockwise.font.textAlign = ex.TextAlign.Center; engine.add(labelCounterClockwise); diff --git a/sandbox/tests/router/index.html b/sandbox/tests/router/index.html index 59538385..06b2b075 100644 --- a/sandbox/tests/router/index.html +++ b/sandbox/tests/router/index.html @@ -1,12 +1,12 @@ - + - - - - Router Test - - - - - - \ No newline at end of file + + + + Router Test + + + + + + diff --git a/sandbox/tests/router/index.ts b/sandbox/tests/router/index.ts index f1dbac1c..b713691d 100644 --- a/sandbox/tests/router/index.ts +++ b/sandbox/tests/router/index.ts @@ -1,26 +1,30 @@ /// var scene1 = new ex.Scene(); -scene1.add(new ex.Label({ - pos: ex.vec(100, 100), - color: ex.Color.Green, - text: 'Scene 1', - z: 99 -})) +scene1.add( + new ex.Label({ + pos: ex.vec(100, 100), + color: ex.Color.Green, + text: 'Scene 1', + z: 99 + }) +); scene1.onInitialize = () => { scene1.camera.pos = ex.vec(200, 200); scene1.camera.zoom = 2; -} +}; var scene2 = new ex.Scene(); scene2.onInitialize = () => { scene2.camera.pos = ex.vec(200, 200); scene2.camera.zoom = 2; -} -scene2.add(new ex.Label({ - pos: ex.vec(100, 100), - color: ex.Color.Violet, - text: 'Scene 2', - z: 99 -})) +}; +scene2.add( + new ex.Label({ + pos: ex.vec(100, 100), + color: ex.Color.Violet, + text: 'Scene 2', + z: 99 + }) +); class MyLoader extends ex.DefaultLoader { onDraw(ctx: CanvasRenderingContext2D): void { @@ -30,7 +34,7 @@ class MyLoader extends ex.DefaultLoader { } class MyCustomScene extends ex.Scene { - onTransition(direction: "in" | "out") { + onTransition(direction: 'in' | 'out') { return new ex.FadeInOut({ direction, color: ex.Color.Violet, @@ -58,15 +62,15 @@ let scenes = { scene1: { scene: scene1, transitions: { - in: new ex.FadeInOut({duration: 500, direction: 'in'}) + in: new ex.FadeInOut({ duration: 500, direction: 'in' }) } }, scene2: { scene: scene2, loader: MyLoader, transitions: { - out: new ex.FadeInOut({duration: 500, direction: 'out'}), - in: new ex.CrossFade({duration: 2500, direction: 'in', blockInput: true}) + out: new ex.FadeInOut({ duration: 500, direction: 'out' }), + in: new ex.CrossFade({ duration: 2500, direction: 'in', blockInput: true }) } }, scene3: MyCustomScene @@ -79,22 +83,22 @@ var gameWithTransitions = new ex.Engine({ scenes }); - var actor = new ex.Actor({ width: 100, height: 100, pos: ex.vec(100, 100), color: ex.Color.Red -}) -actor.addChild(new ex.Actor({ - width: 100, - height: 100, - pos: ex.vec(100, 100), - color: ex.Color.Black -})); +}); +actor.addChild( + new ex.Actor({ + width: 100, + height: 100, + pos: ex.vec(100, 100), + color: ex.Color.Black + }) +); scene1.add(actor); - scene2.onPreLoad = (loader) => { const image1 = new ex.ImageSource('./spritefont.png?=1'); const image2 = new ex.ImageSource('./spritefont.png?=2'); @@ -106,18 +110,20 @@ scene2.onPreLoad = (loader) => { loader.addResource(image3); loader.addResource(image4); loader.addResource(sword); -} +}; scene1.onActivate = () => { setTimeout(() => { gameWithTransitions.goto('scene2'); }, 1000); -} -scene2.add(new ex.Actor({ - width: 100, - height: 100, - pos: ex.vec(400, 400), - color: ex.Color.Blue -})); +}; +scene2.add( + new ex.Actor({ + width: 100, + height: 100, + pos: ex.vec(400, 400), + color: ex.Color.Blue + }) +); var boot = new ex.Loader() as ex.Loader; const image1 = new ex.ImageSource('./spritefont.png?=1'); @@ -130,7 +136,7 @@ boot.addResource(image2); boot.addResource(image3); boot.addResource(image4); boot.addResource(sword); -gameWithTransitions.input.keyboard.on('press', evt => { +gameWithTransitions.input.keyboard.on('press', (evt) => { gameWithTransitions.goto('scene3', { sceneActivationData: { data: 1 } }); @@ -147,7 +153,6 @@ var startTransition = new ex.FadeInOut({ // console.log(game.currentScene.entities); // console.log('killed!'); // }) -gameWithTransitions.start('scene1', -{ +gameWithTransitions.start('scene1', { inTransition: startTransition -}); \ No newline at end of file +}); diff --git a/sandbox/tests/scale/scale.html b/sandbox/tests/scale/scale.html index f31adde9..3c91040f 100644 --- a/sandbox/tests/scale/scale.html +++ b/sandbox/tests/scale/scale.html @@ -1,13 +1,13 @@ - + - - - - - Document - - - - - - \ No newline at end of file + + + + + Document + + + + + + diff --git a/sandbox/tests/scale/scale.ts b/sandbox/tests/scale/scale.ts index 825d7990..789da35a 100644 --- a/sandbox/tests/scale/scale.ts +++ b/sandbox/tests/scale/scale.ts @@ -16,10 +16,10 @@ for (var r in resources) { loader.addResource(resources[r]); } -var target = new ex.Actor({x: 500, y: 500, width: 20, height: 20, color: ex.Color.Red}); +var target = new ex.Actor({ x: 500, y: 500, width: 20, height: 20, color: ex.Color.Red }); game.add(target); -var aim = new ex.Actor({x: game.halfDrawWidth, y: game.halfDrawHeight, width: 100, height: 10, color: ex.Color.Black}); +var aim = new ex.Actor({ x: game.halfDrawWidth, y: game.halfDrawHeight, width: 100, height: 10, color: ex.Color.Black }); aim.graphics.add(resources.txPlayer.toSprite()); aim.scale.setTo(1, 0.2); game.add(aim); diff --git a/sandbox/tests/scene-input/index.html b/sandbox/tests/scene-input/index.html index 7f7fcbbc..e054d80d 100644 --- a/sandbox/tests/scene-input/index.html +++ b/sandbox/tests/scene-input/index.html @@ -1,12 +1,12 @@ - + - - - - Scene Input - - - - - - \ No newline at end of file + + + + Scene Input + + + + + + diff --git a/sandbox/tests/scene-input/index.ts b/sandbox/tests/scene-input/index.ts index cf1ae3a2..5482a2b2 100644 --- a/sandbox/tests/scene-input/index.ts +++ b/sandbox/tests/scene-input/index.ts @@ -8,18 +8,22 @@ const font = new ex.Font({ class SceneWithInput extends ex.Scene { onInitialize(engine: ex.Engine): void { - this.add(new ex.Label({ - pos: ex.vec(200, 200), - text: 'Scene 1', - font - })); + this.add( + new ex.Label({ + pos: ex.vec(200, 200), + text: 'Scene 1', + font + }) + ); - this.add(new ex.Actor({ - pos: ex.vec(400, 400), - width: 200, - height: 200, - color: ex.Color.Red - })); + this.add( + new ex.Actor({ + pos: ex.vec(400, 400), + width: 200, + height: 200, + color: ex.Color.Red + }) + ); this.input.pointers.on('down', () => { console.log('pointer down from scene1'); @@ -28,18 +32,22 @@ class SceneWithInput extends ex.Scene { } class OtherSceneWithInput extends ex.Scene { onInitialize(engine: ex.Engine): void { - this.add(new ex.Label({ - pos: ex.vec(200, 200), - text: 'Scene 2', - font - })); + this.add( + new ex.Label({ + pos: ex.vec(200, 200), + text: 'Scene 2', + font + }) + ); - this.add(new ex.Actor({ - pos: ex.vec(400, 400), - width: 200, - height: 200, - color: ex.Color.Violet - })); + this.add( + new ex.Actor({ + pos: ex.vec(400, 400), + width: 200, + height: 200, + color: ex.Color.Violet + }) + ); this.input.pointers.on('down', () => { console.log('pointer down from scene2'); @@ -51,8 +59,8 @@ var engineWithInput = new ex.Engine({ width: 800, height: 800, scenes: { - scene1: { scene: SceneWithInput, transitions: {in: new ex.CrossFade({duration: 1000, blockInput: true})}}, - scene2: { scene: OtherSceneWithInput, transitions: {in: new ex.CrossFade({duration: 1000, blockInput: true})}} + scene1: { scene: SceneWithInput, transitions: { in: new ex.CrossFade({ duration: 1000, blockInput: true }) } }, + scene2: { scene: OtherSceneWithInput, transitions: { in: new ex.CrossFade({ duration: 1000, blockInput: true }) } } } }); @@ -60,10 +68,10 @@ engineWithInput.input.pointers.on('down', () => { console.log('pointer down from engine'); }); -engineWithInput.input.keyboard.on('press', e => { +engineWithInput.input.keyboard.on('press', (e) => { if (e.key === ex.Keys.Space) { engineWithInput.currentSceneName === 'scene1' ? engineWithInput.goto('scene2') : engineWithInput.goto('scene1'); } -}) +}); -engineWithInput.start('scene1'); \ No newline at end of file +engineWithInput.start('scene1'); diff --git a/sandbox/tests/scene/lifecycle.html b/sandbox/tests/scene/lifecycle.html index 4a708950..fb7d97c0 100644 --- a/sandbox/tests/scene/lifecycle.html +++ b/sandbox/tests/scene/lifecycle.html @@ -1,10 +1,9 @@ - + - + Scene Lifecycle Sample - - - + + @@ -14,5 +13,5 @@ - + diff --git a/sandbox/tests/scene/lifecycle.ts b/sandbox/tests/scene/lifecycle.ts index 7554ed9f..91ffdb3f 100644 --- a/sandbox/tests/scene/lifecycle.ts +++ b/sandbox/tests/scene/lifecycle.ts @@ -1,24 +1,23 @@ /// - ex.Logger.getInstance().defaultLevel = ex.LogLevel.Debug; class MyGame2 extends ex.Engine { constructor(args: ex.EngineOptions) { super(args); - console.log("engine constructor"); + console.log('engine constructor'); this.currentScene.onInitialize = () => { - console.log("scene init"); - } + console.log('scene init'); + }; this.currentScene.onActivate = () => { - console.log("scene activate"); - } + console.log('scene activate'); + }; this.currentScene.onDeactivate = () => { - console.log("scene deactivate"); - } + console.log('scene deactivate'); + }; } async onInitialize() { - console.log("engine init"); + console.log('engine init'); } } @@ -28,10 +27,10 @@ var scene2 = new ex.Scene(); mygame.add('scene2', scene2); -var actor1 = new ex.Actor({x: 60, y: 60, width: 20, height: 20, color: ex.Color.Blue}); +var actor1 = new ex.Actor({ x: 60, y: 60, width: 20, height: 20, color: ex.Color.Blue }); mygame.add(actor1); -var actor2 = new ex.Actor({x: 60, y: 60, width: 20, height: 20, color: ex.Color.Red}); +var actor2 = new ex.Actor({ x: 60, y: 60, width: 20, height: 20, color: ex.Color.Red }); scene2.add(actor2); var loader = new ex.Loader([new ex.ImageSource('https://cdn.rawgit.com/excaliburjs/Excalibur/7dd48128/assets/sword.png')]); diff --git a/sandbox/tests/scenepredraw/index.html b/sandbox/tests/scenepredraw/index.html index d5738a85..8d51cad7 100644 --- a/sandbox/tests/scenepredraw/index.html +++ b/sandbox/tests/scenepredraw/index.html @@ -1,14 +1,14 @@ - + - - - - - Scene Predraw Opacity - - -

All rectangles should have some transparency

- - - - \ No newline at end of file + + + + + Scene Predraw Opacity + + +

All rectangles should have some transparency

+ + + + diff --git a/sandbox/tests/scenepredraw/index.ts b/sandbox/tests/scenepredraw/index.ts index d2384cfa..a5741755 100644 --- a/sandbox/tests/scenepredraw/index.ts +++ b/sandbox/tests/scenepredraw/index.ts @@ -1,19 +1,20 @@ - var paddle = new ex.Actor({ - x: 150, y: 150, - width: 200, height: 200, + x: 150, + y: 150, + width: 200, + height: 200, color: ex.Color.Chartreuse }); var paddle2 = new ex.Actor({ - x: 170, y: 170, - width: 200, height: 200, + x: 170, + y: 170, + width: 200, + height: 200, color: ex.Color.White }); - class MyScene extends ex.Scene { - public onPreDraw(ctx: ex.ExcaliburGraphicsContext) { ctx.save(); ctx.opacity = 0.2; @@ -24,7 +25,6 @@ class MyScene extends ex.Scene { } } - class CustomDraw extends ex.System { public readonly systemType = ex.SystemType.Draw; @@ -44,14 +44,14 @@ class CustomDraw extends ex.System { public preupdate(): void { // Graphics context could be switched to fallback in a new frame if (this._engine == null) { - throw new Error("Uninitialized ObjectSystem"); + throw new Error('Uninitialized ObjectSystem'); } this._graphicsContext = this._engine.graphicsContext; } - public update( delta: number) { + public update(delta: number) { if (this._graphicsContext == null) { - throw new Error("Uninitialized ObjectSystem"); + throw new Error('Uninitialized ObjectSystem'); } const ctx = this._graphicsContext; @@ -60,12 +60,11 @@ class CustomDraw extends ex.System { ctx.drawRectangle(ex.vec(0, 0), 100, 100, ex.Color.White); ctx.restore(); } - } var game = new ex.Engine({ width: 800, - height: 600, + height: 600 }); var theScene = new MyScene(); @@ -76,4 +75,4 @@ game.goToScene('test'); game.add(paddle); game.add(paddle2); -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/screen/index.html b/sandbox/tests/screen/index.html index de2c86fb..ffcb3c2e 100644 --- a/sandbox/tests/screen/index.html +++ b/sandbox/tests/screen/index.html @@ -1,38 +1,38 @@ - + - - - - - Screen - - - -
- -
-
-

The game screen should resize to fit the bordered rectangle and maintain aspect ratio

- - - - -
- - - - \ No newline at end of file + + + + + Screen + + + +
+ +
+
+

The game screen should resize to fit the bordered rectangle and maintain aspect ratio

+ + + + +
+ + + + diff --git a/sandbox/tests/screen/screen.ts b/sandbox/tests/screen/screen.ts index 8075017e..d9f0e2ec 100644 --- a/sandbox/tests/screen/screen.ts +++ b/sandbox/tests/screen/screen.ts @@ -1,17 +1,15 @@ - var widthEl = document.getElementById('containerWidth') as HTMLInputElement; var heightEl = document.getElementById('containerHeight') as HTMLInputElement; var container = document.getElementsByClassName('game-container').item(0) as HTMLDivElement; -widthEl.addEventListener('input', e => { - container.style.width = (e.target as any).value + 'vw'; +widthEl.addEventListener('input', (e) => { + container.style.width = (e.target as any).value + 'vw'; }); -heightEl.addEventListener('input', e => { +heightEl.addEventListener('input', (e) => { container.style.height = (e.target as any).value + 'vh'; }); - var game = new ex.Engine({ canvasElementId: 'game', width: 800, @@ -20,4 +18,4 @@ var game = new ex.Engine({ pointerScope: ex.PointerScope.Canvas }); -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/screenelement/index.html b/sandbox/tests/screenelement/index.html index b58b83c5..6aefe62a 100644 --- a/sandbox/tests/screenelement/index.html +++ b/sandbox/tests/screenelement/index.html @@ -1,13 +1,13 @@ - + - - - - - Screen Element - - - - - - \ No newline at end of file + + + + + Screen Element + + + + + + diff --git a/sandbox/tests/screenelement/index.ts b/sandbox/tests/screenelement/index.ts index a9840262..1a76ae60 100644 --- a/sandbox/tests/screenelement/index.ts +++ b/sandbox/tests/screenelement/index.ts @@ -1,4 +1,3 @@ - var engine = new ex.Engine({ width: 600, height: 400 @@ -26,4 +25,4 @@ screenElement.graphics.use(image.toSprite(), { anchor: ex.vec(0.5, 0.5) }); engine.currentScene.add(screenElement); -engine.start(loader); \ No newline at end of file +engine.start(loader); diff --git a/sandbox/tests/screenelementpointer/index.html b/sandbox/tests/screenelementpointer/index.html index c454b9fe..1f65281c 100644 --- a/sandbox/tests/screenelementpointer/index.html +++ b/sandbox/tests/screenelementpointer/index.html @@ -1,13 +1,13 @@ - + - - - - Pointer on Screen Element - - -

Click the ScreenElement an alert should fire

- - - - \ No newline at end of file + + + + Pointer on Screen Element + + +

Click the ScreenElement an alert should fire

+ + + + diff --git a/sandbox/tests/screenelementpointer/index.ts b/sandbox/tests/screenelementpointer/index.ts index d64a5ba0..f31f0b44 100644 --- a/sandbox/tests/screenelementpointer/index.ts +++ b/sandbox/tests/screenelementpointer/index.ts @@ -1,22 +1,24 @@ - class StartButton extends ex.ScreenElement { - constructor(x: number, y: number) { - super({ - x, y - }) - } - onInitialize() { - this.graphics.use(new ex.Rectangle({ - color: ex.Color.Green, - width: 300, - height: 50 - })); - // ... - this.on('pointerup', () => { - alert("I've been clicked"); - }) - // ... - } + constructor(x: number, y: number) { + super({ + x, + y + }); + } + onInitialize() { + this.graphics.use( + new ex.Rectangle({ + color: ex.Color.Green, + width: 300, + height: 50 + }) + ); + // ... + this.on('pointerup', () => { + alert("I've been clicked"); + }); + // ... + } } var engine = new ex.Engine({ @@ -26,4 +28,4 @@ var engine = new ex.Engine({ engine.add(new StartButton(400, 200)); -engine.start(); \ No newline at end of file +engine.start(); diff --git a/sandbox/tests/side-collision/index.html b/sandbox/tests/side-collision/index.html index 5d01e48d..2e3446cb 100644 --- a/sandbox/tests/side-collision/index.html +++ b/sandbox/tests/side-collision/index.html @@ -1,14 +1,14 @@ - + - - - - - Side Collision - - -

There should be no left right collisions in the console when sliding on the floor

- - - - \ No newline at end of file + + + + + Side Collision + + +

There should be no left right collisions in the console when sliding on the floor

+ + + + diff --git a/sandbox/tests/side-collision/index.ts b/sandbox/tests/side-collision/index.ts index 7ebb316a..1328ba56 100644 --- a/sandbox/tests/side-collision/index.ts +++ b/sandbox/tests/side-collision/index.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 400, height: 400, @@ -19,17 +18,15 @@ class Player2 extends ex.Actor { collisionType: ex.CollisionType.Active, color: ex.Color.Red }); - - } onInitialize() { // onPostCollision is an event, not a lifecycle meaning it can be subscribed to by other things - this.on("postcollision", (evt) => this.onPostCollision(evt)); + this.on('postcollision', (evt) => this.onPostCollision(evt)); } onPostCollision(evt) { - if (evt.side === "Left" || evt.side === "Right") { + if (evt.side === 'Left' || evt.side === 'Right') { console.error(evt.side); } diff --git a/sandbox/tests/side-collision2/index.html b/sandbox/tests/side-collision2/index.html index 3046c191..091fb688 100644 --- a/sandbox/tests/side-collision2/index.html +++ b/sandbox/tests/side-collision2/index.html @@ -1,14 +1,14 @@ - + - - - - - Side Collision - - -

Arcade solver collisions shouldn't clip on the edge of a collider and cancel velocity

- - - - \ No newline at end of file + + + + + Side Collision + + +

Arcade solver collisions shouldn't clip on the edge of a collider and cancel velocity

+ + + + diff --git a/sandbox/tests/side-collision2/index.ts b/sandbox/tests/side-collision2/index.ts index a1fe975a..3a40d68b 100644 --- a/sandbox/tests/side-collision2/index.ts +++ b/sandbox/tests/side-collision2/index.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 400, height: 400, @@ -23,7 +22,7 @@ class Player3 extends ex.Actor { onInitialize() { // onPostCollision is an event, not a lifecycle meaning it can be subscribed to by other things - this.on("postcollision", (evt) => this.onPostCollision(evt)); + this.on('postcollision', (evt) => this.onPostCollision(evt)); } onPostCollision(evt) { diff --git a/sandbox/tests/sound-loop/index.html b/sandbox/tests/sound-loop/index.html index 8f7ecf3e..34f14849 100644 --- a/sandbox/tests/sound-loop/index.html +++ b/sandbox/tests/sound-loop/index.html @@ -1,13 +1,13 @@ - + - - - - Sound Loop Test - - - Stopping a looping sounds should stop all running tracks - - - - \ No newline at end of file + + + + Sound Loop Test + + + Stopping a looping sounds should stop all running tracks + + + + diff --git a/sandbox/tests/sound-loop/index.ts b/sandbox/tests/sound-loop/index.ts index 1cf589a6..2cf40099 100644 --- a/sandbox/tests/sound-loop/index.ts +++ b/sandbox/tests/sound-loop/index.ts @@ -1,17 +1,14 @@ - - var game = new ex.Engine({ width: 400, height: 400 }); var sound = new ex.Sound('./gba1complete.mp3'); -sound.volume = .05; +sound.volume = 0.05; sound.loop = true; - var loader = new ex.Loader(); -loader.addResource(sound) +loader.addResource(sound); class BaseScene extends ex.Scene { constructor(public name) { @@ -27,9 +24,9 @@ class BaseScene extends ex.Scene { } } -var scene11 = new BaseScene("scene1"); -var scene22 = new BaseScene("scene2"); -var scene33 = new BaseScene("scene3"); +var scene11 = new BaseScene('scene1'); +var scene22 = new BaseScene('scene2'); +var scene33 = new BaseScene('scene3'); game.add('scene1', scene11); game.add('scene2', scene22); @@ -41,8 +38,7 @@ game.start(loader).then(() => { setTimeout(() => { game.goToScene('scene1'); sound.stop(); - }, 1000) + }, 1000); }); // going to the same scene again causes the sound to become unstoppable?!?! - diff --git a/sandbox/tests/sound/index.html b/sandbox/tests/sound/index.html index 7dcffc36..36959d4f 100644 --- a/sandbox/tests/sound/index.html +++ b/sandbox/tests/sound/index.html @@ -1,26 +1,18 @@ - + - - - - - Sound - - - - - - - 1.0 - - - - \ No newline at end of file + + + + + Sound + + + + + + + 1.0 + + + + diff --git a/sandbox/tests/sound/sound.ts b/sandbox/tests/sound/sound.ts index 1318283f..3ab3a7b7 100644 --- a/sandbox/tests/sound/sound.ts +++ b/sandbox/tests/sound/sound.ts @@ -4,12 +4,8 @@ var game = new ex.Engine({ height: 400 }); - - var sound = new ex.Sound('./loop.mp3'); -var loader = new ex.Loader([ - sound -]); +var loader = new ex.Loader([sound]); var currentTimeLabel = new ex.Label({ x: 50, @@ -75,7 +71,7 @@ game.currentScene.add(pause); var loopCheckbox = document.querySelector('#loop') as HTMLInputElement; loopCheckbox.onchange = (e) => { sound.loop = !!(e.target as any).value; -} +}; var playbackRate = document.querySelector('#playback-rate') as HTMLInputElement; var playbackValue = document.querySelector('#playback-rate-value') as HTMLInputElement; @@ -87,6 +83,6 @@ playbackRate.oninput = () => { game.currentScene.onPostUpdate = () => { currentTimeLabel.text = 'Current Time: ' + sound.getPlaybackPosition().toFixed(2); totalTimeLabel.text = 'Total Time: ' + sound.getTotalPlaybackDuration().toFixed(2); -} +}; -game.start(loader); \ No newline at end of file +game.start(loader); diff --git a/sandbox/tests/sprite-tint/index.html b/sandbox/tests/sprite-tint/index.html index 9499c127..ce372c6f 100644 --- a/sandbox/tests/sprite-tint/index.html +++ b/sandbox/tests/sprite-tint/index.html @@ -1,13 +1,13 @@ - + - - - - - Sprite Tint - - - - - - \ No newline at end of file + + + + + Sprite Tint + + + + + + diff --git a/sandbox/tests/sprite-tint/index.ts b/sandbox/tests/sprite-tint/index.ts index 2aa0f359..ef731136 100644 --- a/sandbox/tests/sprite-tint/index.ts +++ b/sandbox/tests/sprite-tint/index.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 800, height: 600 @@ -8,7 +7,7 @@ var tex = new ex.ImageSource('https://cdn.rawgit.com/excaliburjs/Excalibur/7dd48 var loader = new ex.Loader([tex]); -var actor = new ex.Actor({x: game.halfDrawWidth, y: game.halfDrawHeight, width: 50, height: 50}); +var actor = new ex.Actor({ x: game.halfDrawWidth, y: game.halfDrawHeight, width: 50, height: 50 }); game.add(actor); var sprite: ex.Sprite; @@ -23,7 +22,7 @@ actor.onInitialize = () => { }); actor.graphics.add(sprite); shadow = actor.graphics.add( - "shadow", + 'shadow', new ex.Sprite({ image: sprite.image, origin: ex.vec(1, 1), @@ -34,52 +33,23 @@ actor.onInitialize = () => { }, tint: ex.Color.fromRGB(0, 0, 0), // Semi-transparent black for shadow opacity: 0.5, - scale: ex.vec(1.2, 1), // Stretched horizontally and squashed vertically to look like a shadow + scale: ex.vec(1.2, 1) // Stretched horizontally and squashed vertically to look like a shadow }) ); const group = new ex.GraphicsGroup({ - members: [ - {graphic: shadow, offset: ex.vec(10, 10)}, - sprite - ] - }) + members: [{ graphic: shadow, offset: ex.vec(10, 10) }, sprite] + }); actor.graphics.use(group); }; - - let currentHue = 0; let currentColor = ex.Color.fromHSL(currentHue, 0.6, 0.6); actor.onPostUpdate = () => { - currentHue = (currentHue + .02) % 1; + currentHue = (currentHue + 0.02) % 1; currentColor = ex.Color.fromHSL(currentHue, 0.6, 0.6); sprite.tint = currentColor; -} - - - - - - - - - - - - - - - - - - - - - - - +}; game.start(loader); - diff --git a/sandbox/tests/sprite/sprite.html b/sandbox/tests/sprite/sprite.html index 19c5e486..ed5b40a3 100644 --- a/sandbox/tests/sprite/sprite.html +++ b/sandbox/tests/sprite/sprite.html @@ -1,16 +1,16 @@ - + - - - - - Document - - - + + + + + Document + + + -
Open the console there should be no errors in firefox or chrome - - - - \ No newline at end of file +
Open the console there should be no errors in firefox or chrome + + + + diff --git a/sandbox/tests/sprite/sprite.ts b/sandbox/tests/sprite/sprite.ts index 36faeb27..a8caeccd 100644 --- a/sandbox/tests/sprite/sprite.ts +++ b/sandbox/tests/sprite/sprite.ts @@ -5,16 +5,15 @@ var game = new ex.Engine({ width: 600, height: 400, displayMode: ex.DisplayMode.FitScreenAndFill, - pixelArt: true, + pixelArt: true // antialiasing: false }); - var tex = new ex.ImageSource('https://cdn.rawgit.com/excaliburjs/Excalibur/7dd48128/assets/sword.png'); var loader = new ex.Loader([tex]); -var actor = new ex.Actor({x: 100, y: 100, width: 50, height: 50}); +var actor = new ex.Actor({ x: 100, y: 100, width: 50, height: 50 }); actor.onInitialize = () => { var sprite = new ex.Sprite({ image: tex, @@ -30,4 +29,4 @@ game.start(loader); game.currentScene.camera.pos = actor.pos; game.currentScene.camera.zoom = 7; -actor.angularVelocity = .1; +actor.angularVelocity = 0.1; diff --git a/sandbox/tests/spritefont/spritefont.html b/sandbox/tests/spritefont/spritefont.html index 63bb5aa6..3a38b2ee 100644 --- a/sandbox/tests/spritefont/spritefont.html +++ b/sandbox/tests/spritefont/spritefont.html @@ -1,68 +1,67 @@ - + - + Sprite Font - - - + + -
+
-
+
- + - -
- + +
+ - + - -
+ +
- + - - -
+ + +
-
+
- + diff --git a/sandbox/tests/spritefont/spritefont.ts b/sandbox/tests/spritefont/spritefont.ts index f6f67ff2..180b5d60 100644 --- a/sandbox/tests/spritefont/spritefont.ts +++ b/sandbox/tests/spritefont/spritefont.ts @@ -16,11 +16,10 @@ var spriteFontSheet = ex.SpriteSheet.fromImageSource({ spriteHeight: 16, spriteWidth: 16 } -}) +}); var label: ex.Label = null; var loader = new ex.Loader([spriteFontTex]); - game.start(loader).then(() => { var spriteFont = new ex.SpriteFont({ spriteSheet: spriteFontSheet, @@ -29,8 +28,8 @@ game.start(loader).then(() => { }); label = new ex.Label({ - text: 'This is a sprite Font test', - x: game.halfDrawWidth, + text: 'This is a sprite Font test', + x: game.halfDrawWidth, y: game.halfDrawHeight, spriteFont: spriteFont }); @@ -40,47 +39,47 @@ game.start(loader).then(() => { game.add(label); }); -document.getElementById('lighten').addEventListener('click', function() { +document.getElementById('lighten').addEventListener('click', function () { label.opacity -= 0.05; }); -document.getElementById('darken').addEventListener('click', function() { +document.getElementById('darken').addEventListener('click', function () { label.opacity += 0.05; }); -document.getElementById('setcolor').addEventListener('click', function() { +document.getElementById('setcolor').addEventListener('click', function () { var text = (document.getElementById('color')).value; label.color = ex.Color.fromHex(text); label.opacity = label.color.a; }); -document.getElementById('text').addEventListener('keyup', function() { +document.getElementById('text').addEventListener('keyup', function () { label.text = (document.getElementById('text')).value; }); -document.getElementById('textalign').addEventListener('change', function(evt) { +document.getElementById('textalign').addEventListener('change', function (evt) { label.font.textAlign = (ex.TextAlign)[(evt.currentTarget).value]; }); -document.getElementById('basealign').addEventListener('change', function(evt) { +document.getElementById('basealign').addEventListener('change', function (evt) { label.font.baseAlign = (ex.BaseAlign)[(evt.currentTarget).value]; }); -document.getElementById('fontsize').addEventListener('change', function(evt) { +document.getElementById('fontsize').addEventListener('change', function (evt) { label.font.size = (evt.currentTarget).value; }); -document.getElementById('letterspacing').addEventListener('keyup', function(evt) { +document.getElementById('letterspacing').addEventListener('keyup', function (evt) { label.spriteFont.spacing = parseFloat((evt.currentTarget).value); }); -document.getElementById('textshadow').addEventListener('change', function(evt) { +document.getElementById('textshadow').addEventListener('change', function (evt) { var text = (document.getElementById('textshadowcolor')).value; var val = (evt.currentTarget).checked; - label.font.shadow = val ? { offset: ex.vec(5, 5), color: ex.Color.fromHex(text)} : undefined + label.font.shadow = val ? { offset: ex.vec(5, 5), color: ex.Color.fromHex(text) } : undefined; }); -document.getElementById('setshadowcolor').addEventListener('click', function() { +document.getElementById('setshadowcolor').addEventListener('click', function () { var text = (document.getElementById('textshadowcolor')).value; - label.font.shadow ={ offset: ex.vec(5, 5), color: ex.Color.fromHex(text)}; + label.font.shadow = { offset: ex.vec(5, 5), color: ex.Color.fromHex(text) }; }); diff --git a/sandbox/tests/spritefontalign/index.html b/sandbox/tests/spritefontalign/index.html index 2447a2ed..86865e4b 100644 --- a/sandbox/tests/spritefontalign/index.html +++ b/sandbox/tests/spritefontalign/index.html @@ -1,14 +1,14 @@ - + - - - - - Spritefont Align - - -

Text should line up on the left

- - - - \ No newline at end of file + + + + + Spritefont Align + + +

Text should line up on the left

+ + + + diff --git a/sandbox/tests/spritefontalign/index.ts b/sandbox/tests/spritefontalign/index.ts index 132dfc18..621ebd95 100644 --- a/sandbox/tests/spritefontalign/index.ts +++ b/sandbox/tests/spritefontalign/index.ts @@ -1,5 +1,3 @@ - - var game = new ex.Engine({ antialiasing: false, width: 800, @@ -29,44 +27,43 @@ var spriteFont = new ex.SpriteFont({ spriteSheet: spriteFontSheet }); -var loader = new ex.Loader([spriteFontImage]) +var loader = new ex.Loader([spriteFontImage]); var textA = new ex.Text({ font: spriteFont, - text: "1" + text: '1' }); var textAA = new ex.Actor({ anchor: ex.Vector.Zero, x: 100, y: 10, - z: 1, + z: 1 }); textAA.graphics.add(textA); game.add(textAA); var textB = new ex.Text({ font: spriteFont, - text: "22" + text: '22' }); var textBA = new ex.Actor({ anchor: ex.Vector.Zero, x: 100, y: 30, - z: 2, + z: 2 }); textBA.graphics.add(textB); game.add(textBA); - var textC = new ex.Text({ font: spriteFont, - text: "333" + text: '333' }); var textCA = new ex.Actor({ anchor: ex.Vector.Zero, x: 100, y: 50, - z: 2, + z: 2 }); textCA.graphics.add(textC); game.add(textCA); @@ -80,11 +77,11 @@ var normalFont = new ex.Font({ var textNormalA = new ex.Text({ font: normalFont, - text: 'normal', + text: 'normal' }); var textNormalB = new ex.Text({ font: normalFont, - text: 'font\nwith\nmultiple\nlines', + text: 'font\nwith\nmultiple\nlines' }); var textNormalC = new ex.Text({ font: normalFont, @@ -95,7 +92,7 @@ var textNormalC = new ex.Text({ var textNormalAA = new ex.Actor({ anchor: ex.Vector.Zero, x: 100, - y: 80, + y: 80 }); textNormalAA.graphics.use(textNormalA); game.add(textNormalAA); @@ -103,7 +100,7 @@ game.add(textNormalAA); var textNormalBA = new ex.Actor({ anchor: ex.Vector.Zero, x: 100, - y: 100, + y: 100 }); textNormalBA.graphics.use(textNormalB); game.add(textNormalBA); @@ -111,7 +108,7 @@ game.add(textNormalBA); var textNormalCA = new ex.Actor({ anchor: ex.Vector.Zero, x: 100, - y: 180, + y: 180 }); textNormalCA.graphics.use(textNormalC); game.add(textNormalCA); @@ -119,11 +116,9 @@ game.add(textNormalCA); let currentHue1 = 0; let currentColor1 = ex.Color.fromHSL(currentHue1, 0.6, 0.6); textNormalCA.onPostUpdate = () => { - currentHue1 = (currentHue1 + .001) % 1; + currentHue1 = (currentHue1 + 0.001) % 1; currentColor1 = ex.Color.fromHSL(currentHue1, 0.6, 0.6); textNormalC.tint = currentColor1; -} +}; -game.start(loader).then(() => { - -}); \ No newline at end of file +game.start(loader).then(() => {}); diff --git a/sandbox/tests/spritesampling/index.html b/sandbox/tests/spritesampling/index.html index 200d01b7..f6f95646 100644 --- a/sandbox/tests/spritesampling/index.html +++ b/sandbox/tests/spritesampling/index.html @@ -1,13 +1,13 @@ - + - - - - - Sprite Sampling - - - - - - \ No newline at end of file + + + + + Sprite Sampling + + + + + + diff --git a/sandbox/tests/spritesampling/main.ts b/sandbox/tests/spritesampling/main.ts index f3bef837..579b3f14 100644 --- a/sandbox/tests/spritesampling/main.ts +++ b/sandbox/tests/spritesampling/main.ts @@ -2,7 +2,7 @@ var game = new ex.Engine({ displayMode: ex.DisplayMode.Fixed, resolution: { height: 16 * 20, - width: 16 * 20, + width: 16 * 20 }, viewport: { width: 16 * 20, @@ -10,14 +10,11 @@ var game = new ex.Engine({ }, antialiasing: false, snapToPixel: true -}) +}); var heroSpriteImage = new ex.ImageSource('../../images/Hero 01.png', false, ex.ImageFiltering.Pixel); -var loader = new ex.Loader([ - heroSpriteImage -]); - +var loader = new ex.Loader([heroSpriteImage]); class PlayerSample extends ex.Actor { constructor(pos: ex.Vector) { @@ -26,7 +23,7 @@ class PlayerSample extends ex.Actor { width: 16, height: 16, collisionType: ex.CollisionType.Active - }) + }); } onInitialize(engine: ex.Engine): void { @@ -45,17 +42,15 @@ class PlayerSample extends ex.Actor { { graphic: playerSpriteSheet.getSprite(0, 0) as ex.Sprite, duration: 200 }, { graphic: playerSpriteSheet.getSprite(1, 0) as ex.Sprite, duration: 200 }, { graphic: playerSpriteSheet.getSprite(2, 0) as ex.Sprite, duration: 200 }, - { graphic: playerSpriteSheet.getSprite(3, 0) as ex.Sprite, duration: 200 }, + { graphic: playerSpriteSheet.getSprite(3, 0) as ex.Sprite, duration: 200 } ] - }) + }); this.graphics.add('down-idle', downIdle); this.graphics.use('down-idle'); } } - - game.start(loader).then(() => { game.currentScene.camera.pos = ex.vec(16, 16); game.add(new PlayerSample(ex.vec(16, 16))); diff --git a/sandbox/tests/text-bounds/index.ts b/sandbox/tests/text-bounds/index.ts index 4e82c9d7..1eae6e82 100644 --- a/sandbox/tests/text-bounds/index.ts +++ b/sandbox/tests/text-bounds/index.ts @@ -3,7 +3,6 @@ var canvasTxt = window.canvasTxt.default; // or npm install canvas-txt --save // import canvasTxt from 'canvas-txt' - var textGraphic = new ex.Canvas({ width: 200, height: 200, @@ -14,7 +13,7 @@ var textGraphic = new ex.Canvas({ canvasTxt.fontSize = 20; canvasTxt.align = 'left'; // canvasTxt.debug = true //shows debug info - canvasTxt.justify = false + canvasTxt.justify = false; canvasTxt.drawText(ctx, txt, 0, 0, 200, 200); ctx.restore(); } @@ -30,4 +29,4 @@ game.currentScene.camera.pos = ex.vec(0, 0); game.add(textActor); -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/text-wrapping/index.html b/sandbox/tests/text-wrapping/index.html index 9c816f0e..7f285d9c 100644 --- a/sandbox/tests/text-wrapping/index.html +++ b/sandbox/tests/text-wrapping/index.html @@ -1,12 +1,12 @@ - + - - - - Text Wrapping - - - - - - \ No newline at end of file + + + + Text Wrapping + + + + + + diff --git a/sandbox/tests/text-wrapping/main.ts b/sandbox/tests/text-wrapping/main.ts index edf9ee14..82b5a89a 100644 --- a/sandbox/tests/text-wrapping/main.ts +++ b/sandbox/tests/text-wrapping/main.ts @@ -16,16 +16,13 @@ var text = new ex.Text({ }); var textActor = new ex.Actor({ - pos: game.screen.center, + pos: game.screen.center }); textActor.graphics.use(text); game.currentScene.add(textActor); -game.input.keyboard.on('release', ev => { - if (ev.key !== ex.Keys.ShiftLeft && - ev.key !== ex.Keys.ShiftRight && - ev.key !== ex.Keys.Enter && - ev.key !== ex.Keys.Backspace) { +game.input.keyboard.on('release', (ev) => { + if (ev.key !== ex.Keys.ShiftLeft && ev.key !== ex.Keys.ShiftRight && ev.key !== ex.Keys.Enter && ev.key !== ex.Keys.Backspace) { text.text += ev.value; } if (ev.key === ex.Keys.Enter) { @@ -36,4 +33,4 @@ game.input.keyboard.on('release', ev => { } }); -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/textcrash/index.html b/sandbox/tests/textcrash/index.html index 98833151..36b1cd0a 100644 --- a/sandbox/tests/textcrash/index.html +++ b/sandbox/tests/textcrash/index.html @@ -1,14 +1,14 @@ - + - - - - - Text Crash - - -

Click on the screen, numbers should increment, there should be no errors in the console

- - - - \ No newline at end of file + + + + + Text Crash + + +

Click on the screen, numbers should increment, there should be no errors in the console

+ + + + diff --git a/sandbox/tests/textcrash/index.ts b/sandbox/tests/textcrash/index.ts index 3a07c764..67c19087 100644 --- a/sandbox/tests/textcrash/index.ts +++ b/sandbox/tests/textcrash/index.ts @@ -1,4 +1,3 @@ - class GameScene extends ex.Scene { private tilemap!: ex.TileMap; private font!: ex.Font; @@ -9,20 +8,20 @@ class GameScene extends ex.Scene { rows: 24, columns: 16, tileWidth: 32, - tileHeight: 32, + tileHeight: 32 }); engine.add(this.tilemap); this.font = new ex.Font(); // this.font.showDebug = true; this.tilemap.tiles.forEach((tile) => { - tile.data.set("id", 0); + tile.data.set('id', 0); }); - engine.input.pointers.primary.on("down", (event: ex.PointerEvent): void => { + engine.input.pointers.primary.on('down', (event: ex.PointerEvent): void => { this.tilemap.tiles.forEach((tile) => { - const id = tile.data.get("id")!; - tile.data.set("id", id + 1); + const id = tile.data.get('id')!; + tile.data.set('id', id + 1); }); this.updateTilemap(); @@ -31,11 +30,11 @@ class GameScene extends ex.Scene { updateTilemap(): void { this.tilemap.tiles.forEach((tile) => { - const id = tile.data.get("id")!; + const id = tile.data.get('id')!; const text = new ex.Text({ text: `${id}`, - color: ex.Color.White, + color: ex.Color.White // font: this.font }); tile.clearGraphics(); @@ -45,11 +44,11 @@ class GameScene extends ex.Scene { } var game = new ex.Engine({ - width: 1080/2, - height: 1920/2, + width: 1080 / 2, + height: 1920 / 2, displayMode: ex.DisplayMode.FitScreen }); game.addScene('scene', new GameScene()); game.start().then(() => { game.goToScene('scene'); -}); \ No newline at end of file +}); diff --git a/sandbox/tests/tilemap-custom-edge-collider/index.html b/sandbox/tests/tilemap-custom-edge-collider/index.html index 47f55493..14d11bd7 100644 --- a/sandbox/tests/tilemap-custom-edge-collider/index.html +++ b/sandbox/tests/tilemap-custom-edge-collider/index.html @@ -1,14 +1,14 @@ - + - - - - - TileMap Edge Collider - - -

TileMap should support edge colliders, the green collider to the left should work

- - - - \ No newline at end of file + + + + + TileMap Edge Collider + + +

TileMap should support edge colliders, the green collider to the left should work

+ + + + diff --git a/sandbox/tests/tilemap-custom-edge-collider/index.ts b/sandbox/tests/tilemap-custom-edge-collider/index.ts index 30b22abf..d0afde23 100644 --- a/sandbox/tests/tilemap-custom-edge-collider/index.ts +++ b/sandbox/tests/tilemap-custom-edge-collider/index.ts @@ -13,16 +13,18 @@ var tilemap = new ex.TileMap({ }); // Sets properties and graphic to each tile -tilemap.tiles.forEach(tile => { +tilemap.tiles.forEach((tile) => { if (tile.x === 1) { // Graphic symbolizing a path // tile.addGraphic(tilesheet.getSprite(4, 1)); // This works right but copies bounds of the tile tile.solid = true; - tile.addCollider(new ex.EdgeCollider({ - begin: new ex.Vector(0, 0), - end: new ex.Vector(0, 32) - })); + tile.addCollider( + new ex.EdgeCollider({ + begin: new ex.Vector(0, 0), + end: new ex.Vector(0, 32) + }) + ); } else { // Random graphic with no colliders // tile.addGraphic(tilesheet.getSprite(Math.floor(Math.random() * 10), Math.floor(Math.random() * 10))); @@ -36,7 +38,7 @@ var edge = new ex.Actor({ collisionType: ex.CollisionType.Fixed }); -edge.collider.useEdgeCollider(ex.vec(0, 0), ex.vec(0, 100),); +edge.collider.useEdgeCollider(ex.vec(0, 0), ex.vec(0, 100)); game.add(edge); var player = new ex.Actor({ @@ -51,20 +53,20 @@ player.onPostUpdate = () => { player.vel.setTo(0, 0); const speed = 64; if (game.input.keyboard.isHeld(ex.Keys.Right)) { - player.vel.x = speed; + player.vel.x = speed; } if (game.input.keyboard.isHeld(ex.Keys.Left)) { - player.vel.x = -speed; + player.vel.x = -speed; } if (game.input.keyboard.isHeld(ex.Keys.Up)) { - player.vel.y = -speed; + player.vel.y = -speed; } if (game.input.keyboard.isHeld(ex.Keys.Down)) { - player.vel.y = speed; + player.vel.y = speed; } -} +}; game.add(player); -game.currentScene.camera.strategy.elasticToActor(player, .8, .9); +game.currentScene.camera.strategy.elasticToActor(player, 0.8, 0.9); game.currentScene.camera.zoom = 3; -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/tilemap-pack/index.html b/sandbox/tests/tilemap-pack/index.html index bffc4b9e..b3a22e88 100644 --- a/sandbox/tests/tilemap-pack/index.html +++ b/sandbox/tests/tilemap-pack/index.html @@ -1,15 +1,15 @@ - + - - - - - TileMap Packing - - -

TileMap Packing

-

Should collapse bounds into minimum geometry to represent colliders

- - - - \ No newline at end of file + + + + + TileMap Packing + + +

TileMap Packing

+

Should collapse bounds into minimum geometry to represent colliders

+ + + + diff --git a/sandbox/tests/tilemap-pack/index.ts b/sandbox/tests/tilemap-pack/index.ts index 93b43235..864c9c97 100644 --- a/sandbox/tests/tilemap-pack/index.ts +++ b/sandbox/tests/tilemap-pack/index.ts @@ -54,22 +54,22 @@ game.input.pointers.primary.on('down', (evt: ex.PointerEvent) => { let currentPointer!: ex.Vector; game.input.pointers.primary.on('down', (moveEvent) => { - if (moveEvent.button === ex.PointerButton.Right) { - currentPointer = moveEvent.worldPos; - game.currentScene.camera.move(currentPointer, 300, ex.EasingFunctions.EaseInOutCubic); - } + if (moveEvent.button === ex.PointerButton.Right) { + currentPointer = moveEvent.worldPos; + game.currentScene.camera.move(currentPointer, 300, ex.EasingFunctions.EaseInOutCubic); + } }); document.oncontextmenu = () => false; game.input.pointers.primary.on('wheel', (wheelEvent) => { - // wheel up - game.currentScene.camera.pos = currentPointer; - if (wheelEvent.deltaY < 0) { - game.currentScene.camera.zoom *= 1.2; - } else { - game.currentScene.camera.zoom /= 1.2; - } + // wheel up + game.currentScene.camera.pos = currentPointer; + if (wheelEvent.deltaY < 0) { + game.currentScene.camera.zoom *= 1.2; + } else { + game.currentScene.camera.zoom /= 1.2; + } }); game.start().then(() => { diff --git a/sandbox/tests/tilemap/tilemap.html b/sandbox/tests/tilemap/tilemap.html index 590d7967..4a4372be 100644 --- a/sandbox/tests/tilemap/tilemap.html +++ b/sandbox/tests/tilemap/tilemap.html @@ -1,15 +1,15 @@ - + - - - - - Document - - -

TileMap culling

-

Should show the whole tilemap, every red square should have a sprite

- - - - \ No newline at end of file + + + + + Document + + +

TileMap culling

+

Should show the whole tilemap, every red square should have a sprite

+ + + + diff --git a/sandbox/tests/tilemap/tilemap.ts b/sandbox/tests/tilemap/tilemap.ts index bac1824b..919048a5 100644 --- a/sandbox/tests/tilemap/tilemap.ts +++ b/sandbox/tests/tilemap/tilemap.ts @@ -43,11 +43,11 @@ game.add(tm); game.input.pointers.primary.on('down', (evt: ex.PointerEvent) => { var tile = tm.getTileByPoint(evt.worldPos); if (tile) { - if (tile.getGraphics().length) { - tile.clearGraphics(); - } else { - tile.addGraphic(tileSprite); - } + if (tile.getGraphics().length) { + tile.clearGraphics(); + } else { + tile.addGraphic(tileSprite); + } } }); diff --git a/sandbox/tests/triangulation/index.html b/sandbox/tests/triangulation/index.html index 5acf5ba8..fdf3e67e 100644 --- a/sandbox/tests/triangulation/index.html +++ b/sandbox/tests/triangulation/index.html @@ -1,13 +1,13 @@ - + - - - - - Triangulation - - - - - - \ No newline at end of file + + + + + Triangulation + + + + + + diff --git a/sandbox/tests/triangulation/index.ts b/sandbox/tests/triangulation/index.ts index 91a95d63..54c19e93 100644 --- a/sandbox/tests/triangulation/index.ts +++ b/sandbox/tests/triangulation/index.ts @@ -1,4 +1,3 @@ - var game = new ex.Engine({ width: 800, height: 600 @@ -14,33 +13,43 @@ var star: ex.Vector[] = []; var rotation = -Math.PI / 2; for (var i = 0; i < 5; i++) { // outer - star.push(ex.vec(100 * Math.cos((2 * Math.PI * i)/5 + rotation), 100 * Math.sin((2 * Math.PI * i)/5 + rotation) )); + star.push(ex.vec(100 * Math.cos((2 * Math.PI * i) / 5 + rotation), 100 * Math.sin((2 * Math.PI * i) / 5 + rotation))); // inner - star.push(ex.vec(40 * Math.cos((2 * Math.PI * i)/5 + rotation + 2 * Math.PI / 10), 40 * Math.sin((2 * Math.PI * i)/5 + rotation + 2 * Math.PI / 10) )); + star.push( + ex.vec( + 40 * Math.cos((2 * Math.PI * i) / 5 + rotation + (2 * Math.PI) / 10), + 40 * Math.sin((2 * Math.PI * i) / 5 + rotation + (2 * Math.PI) / 10) + ) + ); } star.reverse(); -var starCollider = new ex.PolygonCollider({points: star}); -console.log("Collider Bounds", starCollider.localBounds); -var starGraphic = new ex.Polygon({points: star, color: ex.Color.Yellow}); -console.log("Graphic Bounds", starGraphic.localBounds); +var starCollider = new ex.PolygonCollider({ points: star }); +console.log('Collider Bounds', starCollider.localBounds); +var starGraphic = new ex.Polygon({ points: star, color: ex.Color.Yellow }); +console.log('Graphic Bounds', starGraphic.localBounds); -var actor = new ex.Actor({x: 200, y: 200, collisionType: ex.CollisionType.Active}); +var actor = new ex.Actor({ x: 200, y: 200, collisionType: ex.CollisionType.Active }); // This is an odd quirk but because we center graphics by default, and the star is asymmetric -actor.graphics.use(starGraphic, { offset: ex.vec(0, -10)}); +actor.graphics.use(starGraphic, { offset: ex.vec(0, -10) }); actor.collider.set(starCollider.triangulate()); actor.angularVelocity = 3; game.add(actor); - -var actor2 = new ex.Actor({x: 400, y: 200, collisionType: ex.CollisionType.Active}); +var actor2 = new ex.Actor({ x: 400, y: 200, collisionType: ex.CollisionType.Active }); actor2.collider.set(ex.Shape.Box(100, 100).tessellate()); -actor2.graphics.use(new ex.Rectangle({ width: 100, height: 100, color: ex.Color.Black})); +actor2.graphics.use(new ex.Rectangle({ width: 100, height: 100, color: ex.Color.Black })); actor2.rotation = (Math.PI / 2) * 3; game.add(actor2); - -var ground = new ex.Actor({anchor: ex.Vector.Zero, x: 0, y: 500, width: 800, height: 10, color: ex.Color.Black, collisionType: ex.CollisionType.Fixed}); +var ground = new ex.Actor({ + anchor: ex.Vector.Zero, + x: 0, + y: 500, + width: 800, + height: 10, + color: ex.Color.Black, + collisionType: ex.CollisionType.Fixed +}); game.add(ground); - -game.start(); \ No newline at end of file +game.start(); diff --git a/sandbox/tests/trigger/trigger.html b/sandbox/tests/trigger/trigger.html index 246abcb6..f1be5aa7 100644 --- a/sandbox/tests/trigger/trigger.html +++ b/sandbox/tests/trigger/trigger.html @@ -1,13 +1,12 @@ - + - + UI Actors - - - -

You should see 1 collision start and collision end in the console

+ + +

You should see 1 collision start and collision end in the console

- - - - \ No newline at end of file + + + + diff --git a/sandbox/tests/trigger/trigger.ts b/sandbox/tests/trigger/trigger.ts index b783d0ce..4f9d35b1 100644 --- a/sandbox/tests/trigger/trigger.ts +++ b/sandbox/tests/trigger/trigger.ts @@ -29,7 +29,7 @@ trigger.on('collisionend', (evt: ex.ExitTriggerEvent) => { // game.add(trigger); game.add(trigger); -var actor = new ex.Actor({x: 100, y: 0, width: 10, height: 10}); +var actor = new ex.Actor({ x: 100, y: 0, width: 10, height: 10 }); actor.body.collisionType = ex.CollisionType.Active; actor.vel.y = 10; game.add(actor); diff --git a/sandbox/tests/ui/index.html b/sandbox/tests/ui/index.html index 0a9d229d..75edd2ec 100644 --- a/sandbox/tests/ui/index.html +++ b/sandbox/tests/ui/index.html @@ -1,13 +1,12 @@ - + - + UI Actors - - - -

You should see a full background covering the game dimensions

+ + +

You should see a full background covering the game dimensions

- - - - \ No newline at end of file + + + + diff --git a/sandbox/tests/updating-text/index.html b/sandbox/tests/updating-text/index.html index e9bb4582..48865120 100644 --- a/sandbox/tests/updating-text/index.html +++ b/sandbox/tests/updating-text/index.html @@ -1,21 +1,19 @@ - + + + + + Updating Text + + - - - - Updating Text - - - - - - - - - \ No newline at end of file + + + + + diff --git a/sandbox/tests/updating-text/index.ts b/sandbox/tests/updating-text/index.ts index 1c2c8029..056ce2eb 100644 --- a/sandbox/tests/updating-text/index.ts +++ b/sandbox/tests/updating-text/index.ts @@ -7,30 +7,30 @@ var spriteSheet = ex.SpriteSheet.fromImageSource({ rows: 3, columns: 16, spriteWidth: 16, - spriteHeight: 16, - }, + spriteHeight: 16 + } }); var spriteFont = new ex.SpriteFont({ alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!\'&."?-:% ', caseInsensitive: true, spriteSheet: spriteSheet, - spacing: -8, + spacing: -8 }); class DebugInfo extends ex.ScreenElement { private readonly text = new ex.Text({ font: new ex.Font({ - family: "Gorgeous Pixel", + family: 'Gorgeous Pixel', filtering: ex.ImageFiltering.Pixel, smoothing: false, - size: 8 * SCALE, // trying sizes 5-20 does not fix the issue. + size: 8 * SCALE // trying sizes 5-20 does not fix the issue. }), - text: "", + text: '' }); private readonly spriteFontText = new ex.Text({ - text: "", + text: '', font: spriteFont }); @@ -59,9 +59,10 @@ class Game4 extends ex.Engine { super({ width: 450, height: 450, - resolution: { // removing upscaling does not fix the issue + resolution: { + // removing upscaling does not fix the issue height: 150 * SCALE, - width: 150 * SCALE, + width: 150 * SCALE }, antialiasing: false, suppressHiDPIScaling: true, @@ -70,15 +71,15 @@ class Game4 extends ex.Engine { } initialize() { - this.currentScene.add(new DebugInfo({ x: -4, y: 0 * SCALE})); + this.currentScene.add(new DebugInfo({ x: -4, y: 0 * SCALE })); } } var game4 = new Game4(); // game4.toggleDebug(); -var loader = new ex.Loader() +var loader = new ex.Loader(); loader.addResource(image); loader.addResource(spriteFontImage); game4.initialize(); -game4.start(loader); \ No newline at end of file +game4.start(loader); diff --git a/sandbox/tests/within/within.html b/sandbox/tests/within/within.html index 8c35edcb..fd9b84be 100644 --- a/sandbox/tests/within/within.html +++ b/sandbox/tests/within/within.html @@ -1,14 +1,13 @@ - + - + Within distance - - - -

Block are within 200px of the floor and should be red

-

Minimum distance lines should be drawn

+ + +

Block are within 200px of the floor and should be red

+

Minimum distance lines should be drawn

- - - - \ No newline at end of file + + + + diff --git a/sandbox/tests/within/within.ts b/sandbox/tests/within/within.ts index eef128d6..5eec862d 100644 --- a/sandbox/tests/within/within.ts +++ b/sandbox/tests/within/within.ts @@ -1,178 +1,175 @@ /// -(function() { - - -ex.Physics.acc = new ex.Vector(0, 200); -ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; -var game = new ex.Engine({ - width: 600, - height: 400 -}); -game.showDebug(true); - -var floor = new ex.Actor({ - pos: new ex.Vector(game.halfDrawWidth, game.drawHeight), - anchor: new ex.Vector(0.5, 0.5), - width: game.drawWidth, - height: 40, - color: ex.Color.Black, - collisionType: ex.CollisionType.Fixed -}); - -var block = new ex.Actor({ - pos: new ex.Vector(game.halfDrawWidth + 200, game.drawHeight - 125), - width: 50, - height: 50, - color: ex.Color.Green, - collisionType: ex.CollisionType.Fixed -}); - -var block2 = new ex.Actor({ - pos: new ex.Vector(game.halfDrawWidth, game.drawHeight - 45), - width: 50, - height: 50, - color: ex.Color.Green, - collisionType: ex.CollisionType.Fixed -}); - -var block3 = new ex.Actor({ - pos: new ex.Vector(game.halfDrawWidth, game.drawHeight - 200), - width: 50, - height: 50, - color: ex.Color.Green, - collisionType: ex.CollisionType.Fixed -}); - -var block4 = new ex.Actor({ - pos: new ex.Vector(game.halfDrawWidth, game.drawHeight - 255), - width: 50, - height: 50, - color: ex.Color.Green, - collisionType: ex.CollisionType.Fixed -}); - -var otherCircle = new ex.Actor({ - pos: new ex.Vector(400, 100), - color: ex.Color.Green -}); -otherCircle.collider.useCircleCollider(30); - -var otherBlock = new ex.Actor({ - pos: new ex.Vector(400, 400), - rotation: Math.PI / 4, - color: ex.Color.Red -}); -otherBlock.collider.useBoxCollider(50, 50); - -var circle = new ex.Actor({ - pos: new ex.Vector(300, 300), - color: ex.Color.Green -}); -circle.collider.useCircleCollider(40); - -// circle.onPostDraw = (ctx, delta) => { -// const closestEdge = circle.collider.get().getClosestLineBetween(edge.collider.get()); -// const closestCircle = circle.collider.get().getClosestLineBetween(otherCircle.collider.get()); -// const closestPolygon = circle.collider.get().getClosestLineBetween(otherBlock.collider.get()); - -// ctx.restore(); -// ctx.save(); - -// ctx.fillStyle = ex.Color.Blue.toString(); -// ctx.fillText('Closest edge line length:' + closestEdge.getLength(), circle.pos.x + 20, circle.pos.y + 30); -// ex.Util.DrawUtil.line(ctx, ex.Color.Blue, closestEdge.begin.x, closestEdge.begin.y, closestEdge.end.x, closestEdge.end.y, 3); - -// ctx.fillStyle = ex.Color.Green.toString(); -// ctx.fillText('Closest circle line length:' + closestCircle.getLength(), circle.pos.x + 20, circle.pos.y + 45); -// ex.Util.DrawUtil.line(ctx, ex.Color.Green, closestCircle.begin.x, closestCircle.begin.y, closestCircle.end.x, closestCircle.end.y, 3); - -// ctx.fillStyle = ex.Color.Red.toString(); -// ctx.fillText('Closest polygon line length:' + closestPolygon.getLength(), circle.pos.x + 20, circle.pos.y + 60); -// ex.Util.DrawUtil.line(ctx, ex.Color.Red, closestPolygon.begin.x, closestPolygon.begin.y, closestPolygon.end.x, closestPolygon.end.y, 3); -// }; - -var edge = new ex.Actor({ - pos: new ex.Vector(100, 300), - color: ex.Color.Blue -}); -edge.collider.useEdgeCollider(new ex.Vector(0, 0), new ex.Vector(30, 100)); - -var blocks = [block, block2, block3, block4]; - -blocks.forEach((b) => { - b.onPostUpdate = (engine, delta) => { - if (b.within(floor, 200)) { - b.color = ex.Color.Red; - } else { - b.color = ex.Color.Green; - } - }; - b.graphics.onPostDraw = (ctx, delta) => { - const closestPolygon = b.collider.get().getClosestLineBetween(floor.collider.get()); - const closestCircle = b.collider.get().getClosestLineBetween(circle.collider.get()); - const closestEdge = b.collider.get().getClosestLineBetween(edge.collider.get()); - ctx.restore(); - ctx.save(); - - ctx.debug.drawText('Closest polygon line length:' + closestPolygon.getLength(), b.pos.add(ex.vec(20, 50))); - ctx.drawLine(closestPolygon.begin, closestPolygon.end, ex.Color.Red, 3); - - ctx.debug.drawText('Closest circle line length:' + closestCircle.getLength(), b.pos.add(ex.vec(20, 65))); - ctx.drawLine(closestCircle.begin, closestCircle.end, ex.Color.Green, 3); - - ctx.debug.drawText('Closest edge line length:' + closestEdge.getLength(), b.pos.add(ex.vec(20, 80))); - ctx.drawLine(closestEdge.begin, closestEdge.end, ex.Color.Blue, 3); - }; -}); -if (block.within(floor, 200)) { - block.color = ex.Color.Red; -} - -if (block2.within(floor, 200)) { - block2.color = ex.Color.Red; -} - -if (block3.within(floor, 200)) { - block3.color = ex.Color.Red; -} - -if (block4.within(floor, 200)) { - block4.color = ex.Color.Red; -} - -game.input.keyboard.on('press', (evt) => { - if (evt.key === ex.Keys.R) { - block4.rotation += 0.2; - } - if (evt.key === ex.Keys.E) { - block4.rotation -= 0.2; +(function () { + ex.Physics.acc = new ex.Vector(0, 200); + ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; + var game = new ex.Engine({ + width: 600, + height: 400 + }); + game.showDebug(true); + + var floor = new ex.Actor({ + pos: new ex.Vector(game.halfDrawWidth, game.drawHeight), + anchor: new ex.Vector(0.5, 0.5), + width: game.drawWidth, + height: 40, + color: ex.Color.Black, + collisionType: ex.CollisionType.Fixed + }); + + var block = new ex.Actor({ + pos: new ex.Vector(game.halfDrawWidth + 200, game.drawHeight - 125), + width: 50, + height: 50, + color: ex.Color.Green, + collisionType: ex.CollisionType.Fixed + }); + + var block2 = new ex.Actor({ + pos: new ex.Vector(game.halfDrawWidth, game.drawHeight - 45), + width: 50, + height: 50, + color: ex.Color.Green, + collisionType: ex.CollisionType.Fixed + }); + + var block3 = new ex.Actor({ + pos: new ex.Vector(game.halfDrawWidth, game.drawHeight - 200), + width: 50, + height: 50, + color: ex.Color.Green, + collisionType: ex.CollisionType.Fixed + }); + + var block4 = new ex.Actor({ + pos: new ex.Vector(game.halfDrawWidth, game.drawHeight - 255), + width: 50, + height: 50, + color: ex.Color.Green, + collisionType: ex.CollisionType.Fixed + }); + + var otherCircle = new ex.Actor({ + pos: new ex.Vector(400, 100), + color: ex.Color.Green + }); + otherCircle.collider.useCircleCollider(30); + + var otherBlock = new ex.Actor({ + pos: new ex.Vector(400, 400), + rotation: Math.PI / 4, + color: ex.Color.Red + }); + otherBlock.collider.useBoxCollider(50, 50); + + var circle = new ex.Actor({ + pos: new ex.Vector(300, 300), + color: ex.Color.Green + }); + circle.collider.useCircleCollider(40); + + // circle.onPostDraw = (ctx, delta) => { + // const closestEdge = circle.collider.get().getClosestLineBetween(edge.collider.get()); + // const closestCircle = circle.collider.get().getClosestLineBetween(otherCircle.collider.get()); + // const closestPolygon = circle.collider.get().getClosestLineBetween(otherBlock.collider.get()); + + // ctx.restore(); + // ctx.save(); + + // ctx.fillStyle = ex.Color.Blue.toString(); + // ctx.fillText('Closest edge line length:' + closestEdge.getLength(), circle.pos.x + 20, circle.pos.y + 30); + // ex.Util.DrawUtil.line(ctx, ex.Color.Blue, closestEdge.begin.x, closestEdge.begin.y, closestEdge.end.x, closestEdge.end.y, 3); + + // ctx.fillStyle = ex.Color.Green.toString(); + // ctx.fillText('Closest circle line length:' + closestCircle.getLength(), circle.pos.x + 20, circle.pos.y + 45); + // ex.Util.DrawUtil.line(ctx, ex.Color.Green, closestCircle.begin.x, closestCircle.begin.y, closestCircle.end.x, closestCircle.end.y, 3); + + // ctx.fillStyle = ex.Color.Red.toString(); + // ctx.fillText('Closest polygon line length:' + closestPolygon.getLength(), circle.pos.x + 20, circle.pos.y + 60); + // ex.Util.DrawUtil.line(ctx, ex.Color.Red, closestPolygon.begin.x, closestPolygon.begin.y, closestPolygon.end.x, closestPolygon.end.y, 3); + // }; + + var edge = new ex.Actor({ + pos: new ex.Vector(100, 300), + color: ex.Color.Blue + }); + edge.collider.useEdgeCollider(new ex.Vector(0, 0), new ex.Vector(30, 100)); + + var blocks = [block, block2, block3, block4]; + + blocks.forEach((b) => { + b.onPostUpdate = (engine, delta) => { + if (b.within(floor, 200)) { + b.color = ex.Color.Red; + } else { + b.color = ex.Color.Green; + } + }; + b.graphics.onPostDraw = (ctx, delta) => { + const closestPolygon = b.collider.get().getClosestLineBetween(floor.collider.get()); + const closestCircle = b.collider.get().getClosestLineBetween(circle.collider.get()); + const closestEdge = b.collider.get().getClosestLineBetween(edge.collider.get()); + ctx.restore(); + ctx.save(); + + ctx.debug.drawText('Closest polygon line length:' + closestPolygon.getLength(), b.pos.add(ex.vec(20, 50))); + ctx.drawLine(closestPolygon.begin, closestPolygon.end, ex.Color.Red, 3); + + ctx.debug.drawText('Closest circle line length:' + closestCircle.getLength(), b.pos.add(ex.vec(20, 65))); + ctx.drawLine(closestCircle.begin, closestCircle.end, ex.Color.Green, 3); + + ctx.debug.drawText('Closest edge line length:' + closestEdge.getLength(), b.pos.add(ex.vec(20, 80))); + ctx.drawLine(closestEdge.begin, closestEdge.end, ex.Color.Blue, 3); + }; + }); + if (block.within(floor, 200)) { + block.color = ex.Color.Red; } - var keyDist = 5; - if (evt.key === ex.Keys.Up) { - block4.pos.addEqual(new ex.Vector(0, -keyDist)); + if (block2.within(floor, 200)) { + block2.color = ex.Color.Red; } - if (evt.key === ex.Keys.Down) { - block4.pos.addEqual(new ex.Vector(0, keyDist)); + if (block3.within(floor, 200)) { + block3.color = ex.Color.Red; } - if (evt.key === ex.Keys.Right) { - block4.pos.addEqual(new ex.Vector(keyDist, 0)); + if (block4.within(floor, 200)) { + block4.color = ex.Color.Red; } - if (evt.key === ex.Keys.Left) { - block4.pos.addEqual(new ex.Vector(-keyDist, 0)); - } -}); + game.input.keyboard.on('press', (evt) => { + if (evt.key === ex.Keys.R) { + block4.rotation += 0.2; + } + if (evt.key === ex.Keys.E) { + block4.rotation -= 0.2; + } -game.add(otherCircle); -game.add(otherBlock); -game.add(circle); -game.add(edge); -game.add(block4); -game.add(floor); -game.start(); + var keyDist = 5; + if (evt.key === ex.Keys.Up) { + block4.pos.addEqual(new ex.Vector(0, -keyDist)); + } -})(); \ No newline at end of file + if (evt.key === ex.Keys.Down) { + block4.pos.addEqual(new ex.Vector(0, keyDist)); + } + + if (evt.key === ex.Keys.Right) { + block4.pos.addEqual(new ex.Vector(keyDist, 0)); + } + + if (evt.key === ex.Keys.Left) { + block4.pos.addEqual(new ex.Vector(-keyDist, 0)); + } + }); + + game.add(otherCircle); + game.add(otherBlock); + game.add(circle); + game.add(edge); + game.add(block4); + game.add(floor); + game.start(); +})(); diff --git a/sandbox/tests/zoom/zoom.html b/sandbox/tests/zoom/zoom.html index 0c96ad10..b768f304 100644 --- a/sandbox/tests/zoom/zoom.html +++ b/sandbox/tests/zoom/zoom.html @@ -1,20 +1,19 @@ - + - + - - + + - -
+ +
-

Use +/- keys to zoom in/out

-

Click on the box to make it green at any zoom/focus

-

Arrow keys to move the camera focus

+

Use +/- keys to zoom in/out

+

Click on the box to make it green at any zoom/focus

+

Arrow keys to move the camera focus

- - + diff --git a/sandbox/tests/zoom/zoom.ts b/sandbox/tests/zoom/zoom.ts index f72307c0..6dbb303d 100644 --- a/sandbox/tests/zoom/zoom.ts +++ b/sandbox/tests/zoom/zoom.ts @@ -11,9 +11,9 @@ var raptorTex = new ex.ImageSource('raptor.png'); var raptorSheet = ex.SpriteSheet.fromImageSource({ image: raptorTex, grid: { - columns: 8, - rows:1, - spriteWidth: 64, + columns: 8, + rows: 1, + spriteWidth: 64, spriteHeight: 64 } }); @@ -23,10 +23,10 @@ raptorAnim.scale.setTo(2, 2); game.showDebug(true); var target = new ex.Actor({ - x: game.halfDrawWidth, - y: game.halfDrawHeight, - width: 64 * 2, - height: 64 * 2, + x: game.halfDrawWidth, + y: game.halfDrawHeight, + width: 64 * 2, + height: 64 * 2 }); target.graphics.add(raptorAnim); diff --git a/scripts/excalibur-version.js b/scripts/excalibur-version.js index 503e69e8..bb8fdb0a 100644 --- a/scripts/excalibur-version.js +++ b/scripts/excalibur-version.js @@ -15,4 +15,4 @@ try { replace.sync(options); } catch (e) { console.error(e); -} \ No newline at end of file +} diff --git a/src/browsersupport/BrowserSupportSpec.ts b/src/browsersupport/BrowserSupportSpec.ts index eff7ab2a..83ed22d5 100644 --- a/src/browsersupport/BrowserSupportSpec.ts +++ b/src/browsersupport/BrowserSupportSpec.ts @@ -8,36 +8,36 @@ describe('Browser integration test', () => { height: 800 }); game.start().then(() => { - done() + done(); }); - } + }; expect(boot).not.toThrow(); }); it('should allow pointers', (done) => { - const downSpy = jasmine.createSpy("down"); + const downSpy = jasmine.createSpy('down'); class Game2 extends ex.Engine { initialize() { - const player1 = new ex.Actor({x: 0, y: 0, width: 100, height: 100, color: ex.Color.Red}); + const player1 = new ex.Actor({ x: 0, y: 0, width: 100, height: 100, color: ex.Color.Red }); this.add(player1); player1.z = 10; - player1.on("pointerdown", downSpy); + player1.on('pointerdown', downSpy); return this.start(); } } const pointer = () => { - var game2 = new Game2({width: 600, height: 400}); + const game2 = new Game2({ width: 600, height: 400 }); game2.initialize().then(() => { - game2.input.pointers.triggerEvent("down", ex.vec(0, 0)); + game2.input.pointers.triggerEvent('down', ex.vec(0, 0)); expect(downSpy).toHaveBeenCalledTimes(1); done(); }); - } + }; expect(pointer).not.toThrow(); }); -}); \ No newline at end of file +}); diff --git a/src/engine/Actions/Action/ActionSequence.ts b/src/engine/Actions/Action/ActionSequence.ts index 97df2414..c52f923f 100644 --- a/src/engine/Actions/Action/ActionSequence.ts +++ b/src/engine/Actions/Action/ActionSequence.ts @@ -39,4 +39,4 @@ export class ActionSequence implements Action { public clone(entity: Entity) { return new ActionSequence(entity, this._sequenceBuilder); } -} \ No newline at end of file +} diff --git a/src/engine/Actions/Action/EaseBy.ts b/src/engine/Actions/Action/EaseBy.ts index 838d1a6a..e82c2ab7 100644 --- a/src/engine/Actions/Action/EaseBy.ts +++ b/src/engine/Actions/Action/EaseBy.ts @@ -78,4 +78,4 @@ export class EaseBy implements Action { this._motion.vel = vec(0, 0); this._stopped = true; } -} \ No newline at end of file +} diff --git a/src/engine/Actions/Action/EaseTo.ts b/src/engine/Actions/Action/EaseTo.ts index a033289d..958e949f 100644 --- a/src/engine/Actions/Action/EaseTo.ts +++ b/src/engine/Actions/Action/EaseTo.ts @@ -1,4 +1,4 @@ -import { Entity} from '../../EntityComponentSystem/Entity'; +import { Entity } from '../../EntityComponentSystem/Entity'; import { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent'; import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent'; import { vec, Vector } from '../../Math/vector'; diff --git a/src/engine/Actions/Action/Fade.ts b/src/engine/Actions/Action/Fade.ts index 386f93c1..c5aacf6b 100644 --- a/src/engine/Actions/Action/Fade.ts +++ b/src/engine/Actions/Action/Fade.ts @@ -39,8 +39,7 @@ export class Fade implements Action { } if (this._speed > 0) { - this._graphics.opacity += (this._multiplier * - (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed; + this._graphics.opacity += (this._multiplier * (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed; } this._speed -= delta; diff --git a/src/engine/Actions/Action/MoveTo.ts b/src/engine/Actions/Action/MoveTo.ts index a44e6f9f..9ec7a0bb 100644 --- a/src/engine/Actions/Action/MoveTo.ts +++ b/src/engine/Actions/Action/MoveTo.ts @@ -16,7 +16,12 @@ export class MoveTo implements Action { private _distance: number; private _started = false; private _stopped = false; - constructor(public entity: Entity, destx: number, desty: number, speed: number) { + constructor( + public entity: Entity, + destx: number, + desty: number, + speed: number + ) { this._tx = entity.get(TransformComponent); this._motion = entity.get(MotionComponent); this._end = new Vector(destx, desty); diff --git a/src/engine/Actions/Action/ParallelActions.ts b/src/engine/Actions/Action/ParallelActions.ts index 457c3ba6..d1e4bd06 100644 --- a/src/engine/Actions/Action/ParallelActions.ts +++ b/src/engine/Actions/Action/ParallelActions.ts @@ -1,7 +1,6 @@ import { Entity } from '../../EntityComponentSystem'; import { Action } from '../Action'; - /** * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time */ @@ -18,12 +17,12 @@ export class ParallelActions implements Action { } } isComplete(entity: Entity): boolean { - return this._actions.every(a => a.isComplete(entity)); + return this._actions.every((a) => a.isComplete(entity)); } reset(): void { - this._actions.forEach(a => a.reset()); + this._actions.forEach((a) => a.reset()); } stop(): void { - this._actions.forEach(a => a.stop()); + this._actions.forEach((a) => a.stop()); } -} \ No newline at end of file +} diff --git a/src/engine/Actions/Action/ScaleBy.ts b/src/engine/Actions/Action/ScaleBy.ts index 1d0eadb1..cf539ee9 100644 --- a/src/engine/Actions/Action/ScaleBy.ts +++ b/src/engine/Actions/Action/ScaleBy.ts @@ -51,8 +51,8 @@ export class ScaleBy implements Action { public isComplete(): boolean { return ( this._stopped || - (Math.abs(this._tx.scale.x - this._startScale.x) >= (this._distanceX - 0.01) && - Math.abs(this._tx.scale.y - this._startScale.y) >= (this._distanceY - 0.01)) + (Math.abs(this._tx.scale.x - this._startScale.x) >= this._distanceX - 0.01 && + Math.abs(this._tx.scale.y - this._startScale.y) >= this._distanceY - 0.01) ); } diff --git a/src/engine/Actions/Action/ScaleTo.ts b/src/engine/Actions/Action/ScaleTo.ts index 17c63a5c..de36ff22 100644 --- a/src/engine/Actions/Action/ScaleTo.ts +++ b/src/engine/Actions/Action/ScaleTo.ts @@ -61,8 +61,8 @@ export class ScaleTo implements Action { public isComplete(): boolean { return ( this._stopped || - (Math.abs(this._tx.scale.x - this._startX) >= (this._distanceX - 0.01) && - Math.abs(this._tx.scale.y - this._startY) >= (this._distanceY - 0.01)) + (Math.abs(this._tx.scale.x - this._startX) >= this._distanceX - 0.01 && + Math.abs(this._tx.scale.y - this._startY) >= this._distanceY - 0.01) ); } diff --git a/src/engine/Actions/ActionContext.ts b/src/engine/Actions/ActionContext.ts index 6a924954..247b9ca8 100644 --- a/src/engine/Actions/ActionContext.ts +++ b/src/engine/Actions/ActionContext.ts @@ -67,7 +67,7 @@ export class ActionContext { * @param duration The time it should take the actor to move to the new location in milliseconds * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]] */ - public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext + public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext; /** * This method will move an actor to the specified `x` and `y` position over the * specified duration using a given [[EasingFunctions]] and return back the actor. This @@ -77,7 +77,7 @@ export class ActionContext { * @param duration The time it should take the actor to move to the new location in milliseconds * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]] */ - public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext + public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext; public easeTo(...args: any[]): ActionContext { let x = 0; let y = 0; @@ -242,11 +242,12 @@ export class ActionContext { * @param speedY The speed of scaling specified in magnitude increase per second on Y axis */ public scaleTo(sizeX: number, sizeY: number, speedX: number, speedY: number): ActionContext; - public scaleTo(sizeXOrVector: number | Vector, + public scaleTo( + sizeXOrVector: number | Vector, sizeYOrSpeed: number | Vector, speedXOrUndefined?: number | undefined, - speedYOrUndefined?: number | undefined): ActionContext { - + speedYOrUndefined?: number | undefined + ): ActionContext { let sizeX = 1; let sizeY = 1; let speedX = 0; diff --git a/src/engine/Actions/ActionsComponent.ts b/src/engine/Actions/ActionsComponent.ts index 737c970c..c15d3b5c 100644 --- a/src/engine/Actions/ActionsComponent.ts +++ b/src/engine/Actions/ActionsComponent.ts @@ -10,7 +10,7 @@ import { ActionQueue } from './ActionQueue'; import { RotationType } from './RotationType'; import { Action } from './Action'; -export interface ActionContextMethods extends Pick { }; +export interface ActionContextMethods extends Pick {} export class ActionsComponent extends Component implements ActionContextMethods { dependencies = [TransformComponent, MotionComponent]; @@ -181,7 +181,8 @@ export class ActionsComponent extends Component implements ActionContextMethods sizeXOrVector: number | Vector, sizeYOrSpeed: number | Vector, speedXOrUndefined?: number, - speedYOrUndefined?: number): ActionContext { + speedYOrUndefined?: number + ): ActionContext { return this._getCtx().scaleTo.apply(this._ctx, [sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined] as any); } @@ -324,4 +325,4 @@ export class ActionsComponent extends Component implements ActionContextMethods public toPromise(): Promise { return this._getCtx().toPromise(); } -} \ No newline at end of file +} diff --git a/src/engine/Actions/ActionsSystem.ts b/src/engine/Actions/ActionsSystem.ts index 3d41ddf6..1ea39c0c 100644 --- a/src/engine/Actions/ActionsSystem.ts +++ b/src/engine/Actions/ActionsSystem.ts @@ -12,8 +12,8 @@ export class ActionsSystem extends System { super(); this.query = this.world.query([ActionsComponent]); - this.query.entityAdded$.subscribe(e => this._actions.push(e.get(ActionsComponent))); - this.query.entityRemoved$.subscribe(e => { + this.query.entityAdded$.subscribe((e) => this._actions.push(e.get(ActionsComponent))); + this.query.entityRemoved$.subscribe((e) => { const action = e.get(ActionsComponent); const index = this._actions.indexOf(action); if (index > -1) { @@ -26,4 +26,4 @@ export class ActionsSystem extends System { actions.update(delta); } } -} \ No newline at end of file +} diff --git a/src/engine/Actions/Index.ts b/src/engine/Actions/Index.ts index 8a82f687..1e7491eb 100644 --- a/src/engine/Actions/Index.ts +++ b/src/engine/Actions/Index.ts @@ -24,4 +24,4 @@ export * from './Action/ScaleTo'; export * from './Action/Delay'; export * from './ActionsComponent'; -export * from './ActionsSystem'; \ No newline at end of file +export * from './ActionsSystem'; diff --git a/src/engine/Actions/tsconfig.json b/src/engine/Actions/tsconfig.json index b2e9e0b8..20d5e2e0 100644 --- a/src/engine/Actions/tsconfig.json +++ b/src/engine/Actions/tsconfig.json @@ -3,4 +3,4 @@ "compilerOptions": { "strict": true } -} \ No newline at end of file +} diff --git a/src/engine/Actor.ts b/src/engine/Actor.ts index e2c12520..0cf7d3f3 100644 --- a/src/engine/Actor.ts +++ b/src/engine/Actor.ts @@ -182,7 +182,7 @@ export type ActorEvents = EntityEvents & { exitviewport: ExitViewPortEvent; actionstart: ActionStartEvent; actioncomplete: ActionCompleteEvent; -} +}; export const ActorEvents = { CollisionStart: 'collisionstart', @@ -563,7 +563,7 @@ export class Actor extends Entity implements Eventable, PointerEvents, CanInitia this.z = z ?? 0; this.transform.coordPlane = coordPlane ?? CoordPlane.World; - this.pointer = new PointerComponent; + this.pointer = new PointerComponent(); this.addComponent(this.pointer); this.graphics = new GraphicsComponent({ @@ -573,16 +573,16 @@ export class Actor extends Entity implements Eventable, PointerEvents, CanInitia }); this.addComponent(this.graphics); - this.motion = new MotionComponent; + this.motion = new MotionComponent(); this.addComponent(this.motion); this.vel = vel ?? Vector.Zero; this.acc = acc ?? Vector.Zero; this.angularVelocity = angularVelocity ?? 0; - this.actions = new ActionsComponent; + this.actions = new ActionsComponent(); this.addComponent(this.actions); - this.body = new BodyComponent; + this.body = new BodyComponent(); this.addComponent(this.body); this.body.collisionType = collisionType ?? CollisionType.Passive; if (collisionGroup) { @@ -638,13 +638,13 @@ export class Actor extends Entity implements Eventable, PointerEvents, CanInitia clone.processComponentRemoval(); // Clone builtins, order is important, same as ctor - clone.addComponent(clone.transform = this.transform.clone() as TransformComponent, true); - clone.addComponent(clone.pointer = this.pointer.clone() as PointerComponent, true); - clone.addComponent(clone.graphics = this.graphics.clone() as GraphicsComponent, true); - clone.addComponent(clone.motion = this.motion.clone() as MotionComponent, true); - clone.addComponent(clone.actions = this.actions.clone() as ActionsComponent, true); - clone.addComponent(clone.body = this.body.clone() as BodyComponent, true); - clone.addComponent(clone.collider = this.collider.clone() as ColliderComponent, true); + clone.addComponent((clone.transform = this.transform.clone() as TransformComponent), true); + clone.addComponent((clone.pointer = this.pointer.clone() as PointerComponent), true); + clone.addComponent((clone.graphics = this.graphics.clone() as GraphicsComponent), true); + clone.addComponent((clone.motion = this.motion.clone() as MotionComponent), true); + clone.addComponent((clone.actions = this.actions.clone() as ActionsComponent), true); + clone.addComponent((clone.body = this.body.clone() as BodyComponent), true); + clone.addComponent((clone.collider = this.collider.clone() as ColliderComponent), true); const builtInComponents: Component[] = [ this.transform, @@ -794,7 +794,6 @@ export class Actor extends Entity implements Eventable, PointerEvents, CanInitia return this.get(TransformComponent).z; } - /** * Sets the z-index of an actor and updates it in the drawing list for the scene. * The z-index determines the relative order an actor is drawn in. @@ -812,16 +811,15 @@ export class Actor extends Entity implements Eventable, PointerEvents, CanInitia const globalPos = this.getGlobalPos(); return new Vector( globalPos.x + this.width / 2 - this.anchor.x * this.width, - globalPos.y + this.height / 2 - this.anchor.y * this.height); + globalPos.y + this.height / 2 - this.anchor.y * this.height + ); } /** * Get the local center point of an actor */ public get localCenter(): Vector { - return new Vector( - this.pos.x + this.width / 2 - this.anchor.x * this.width, - this.pos.y + this.height / 2 - this.anchor.y * this.height); + return new Vector(this.pos.x + this.width / 2 - this.anchor.x * this.width, this.pos.y + this.height / 2 - this.anchor.y * this.height); } public get width() { diff --git a/src/engine/Camera.ts b/src/engine/Camera.ts index 5d05cf6e..f1690f8b 100644 --- a/src/engine/Camera.ts +++ b/src/engine/Camera.ts @@ -112,7 +112,10 @@ export class LockCameraToActorStrategy implements CameraStrategy { * Lock a camera to a specific axis around an actor. */ export class LockCameraToActorAxisStrategy implements CameraStrategy { - constructor(public target: Actor, public axis: Axis) {} + constructor( + public target: Actor, + public axis: Axis + ) {} public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => { const center = target.center; const currentFocus = cam.getFocus(); @@ -136,7 +139,11 @@ export class ElasticToActorStrategy implements CameraStrategy { * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target */ - constructor(public target: Actor, public cameraElasticity: number, public cameraFriction: number) {} + constructor( + public target: Actor, + public cameraElasticity: number, + public cameraFriction: number + ) {} public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => { const position = target.center; let focus = cam.getFocus(); @@ -167,7 +174,10 @@ export class RadiusAroundActorStrategy implements CameraStrategy { * @param target Target actor to follow when it is "radius" pixels away * @param radius Number of pixels away before the camera will follow */ - constructor(public target: Actor, public radius: number) {} + constructor( + public target: Actor, + public radius: number + ) {} public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => { const position = target.center; const focus = cam.getFocus(); @@ -230,11 +240,10 @@ export class LimitCameraBoundsStrategy implements CameraStrategy { } export type CameraEvents = { - preupdate: PreUpdateEvent, - postupdate: PostUpdateEvent, - initialize: InitializeEvent, - -} + preupdate: PreUpdateEvent; + postupdate: PostUpdateEvent; + initialize: InitializeEvent; +}; export const CameraEvents = { Initialize: 'initialize', @@ -255,7 +264,6 @@ export class Camera implements CanUpdate, CanInitialize { public transform: AffineMatrix = AffineMatrix.identity(); public inverse: AffineMatrix = AffineMatrix.identity(); - protected _follow: Actor; private _cameraStrategies: CameraStrategy[] = []; @@ -791,9 +799,7 @@ export class Camera implements CanUpdate, CanInitialize { // must happen on the draw, because more draws are potentially happening than updates if (this._engine.fixedUpdateFps) { const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps); - const interpolatedPos = this.pos.scale(blend).add( - this._oldPos.scale(1.0 - blend) - ); + const interpolatedPos = this.pos.scale(blend).add(this._oldPos.scale(1.0 - blend)); interpolatedPos.clone(this.drawPos); this.updateTransform(interpolatedPos); } diff --git a/src/engine/Collision/BodyComponent.ts b/src/engine/Collision/BodyComponent.ts index 1dd5c884..ee931c62 100644 --- a/src/engine/Collision/BodyComponent.ts +++ b/src/engine/Collision/BodyComponent.ts @@ -17,7 +17,7 @@ export interface BodyComponentOptions { type?: CollisionType; group?: CollisionGroup; useGravity?: boolean; - config?: Pick['bodies'] + config?: Pick['bodies']; } export enum DegreeOfFreedom { @@ -88,7 +88,7 @@ export class BodyComponent extends Component implements Clonable ...config }; this.canSleep = this._bodyConfig.canSleepByDefault; - this.sleepMotion = this._bodyConfig.sleepEpsilon * 5; + this.sleepMotion = this._bodyConfig.sleepEpsilon * 5; this.wakeThreshold = this._bodyConfig.wakeThreshold; } /** @@ -138,7 +138,7 @@ export class BodyComponent extends Component implements Clonable /** * Can this body sleep, by default bodies do not sleep */ - public canSleep: boolean;; + public canSleep: boolean; private _sleeping = false; /** @@ -201,7 +201,7 @@ export class BodyComponent extends Component implements Clonable }); const maybeCollider = collider.get(); if (maybeCollider) { - return this._cachedInertia = maybeCollider.getInertia(this.mass); + return (this._cachedInertia = maybeCollider.getInertia(this.mass)); } } return 0; @@ -215,7 +215,7 @@ export class BodyComponent extends Component implements Clonable if (this._cachedInverseInertia) { return this._cachedInverseInertia; } - return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia; + return (this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia); } /** @@ -260,7 +260,7 @@ export class BodyComponent extends Component implements Clonable } public get motion(): MotionComponent { - return this.owner?.get(MotionComponent); + return this.owner?.get(MotionComponent); } public get pos(): Vector { diff --git a/src/engine/Collision/BoundingBox.ts b/src/engine/Collision/BoundingBox.ts index 2b6bce2e..c8613d40 100644 --- a/src/engine/Collision/BoundingBox.ts +++ b/src/engine/Collision/BoundingBox.ts @@ -213,10 +213,10 @@ export class BoundingBox { const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y; return new BoundingBox({ - left,//: topLeft.x, - top,//: topLeft.y, - right,//: bottomRight.x, - bottom//: bottomRight.y + left, //: topLeft.x, + top, //: topLeft.y, + right, //: bottomRight.x, + bottom //: bottomRight.y }); } @@ -229,7 +229,6 @@ export class BoundingBox { return 2 * (wx + wy); } - // Cache bounding box point returns private _points: Vector[] = []; private _left?: number; @@ -241,11 +240,7 @@ export class BoundingBox { * Returns the world space points that make up the corners of the bounding box as a polygon */ public getPoints(): Vector[] { - if (this._left !== this.left || - this._right !== this.right || - this._top !== this.top || - this._bottom !== this.bottom - ) { + if (this._left !== this.left || this._right !== this.right || this._top !== this.top || this._bottom !== this.bottom) { this._points.length = 0; this._points.push(new Vector(this.left, this.top)); this._points.push(new Vector(this.right, this.top)); @@ -356,15 +351,14 @@ export class BoundingBox { */ public overlaps(other: BoundingBox, epsilon?: number): boolean { const e = epsilon || 0; - if (other.hasZeroDimensions()){ + if (other.hasZeroDimensions()) { return this.contains(other); } if (this.hasZeroDimensions()) { return other.contains(this); } const totalBoundingBox = this.combine(other); - return totalBoundingBox.width + e < other.width + this.width && - totalBoundingBox.height + e < other.height + this.height; + return totalBoundingBox.width + e < other.width + this.width && totalBoundingBox.height + e < other.height + this.height; } /** diff --git a/src/engine/Collision/ColliderComponent.ts b/src/engine/Collision/ColliderComponent.ts index b497e343..9a579eae 100644 --- a/src/engine/Collision/ColliderComponent.ts +++ b/src/engine/Collision/ColliderComponent.ts @@ -16,7 +16,6 @@ import { EventEmitter } from '../EventEmitter'; import { Actor } from '../Actor'; export class ColliderComponent extends Component { - public events = new EventEmitter(); /** * Observable that notifies when a collider is added to the body @@ -179,7 +178,8 @@ export class ColliderComponent extends Component { postcollision.other.owner, postcollision.side, postcollision.intersection, - postcollision.contact) + postcollision.contact + ) ); if (entity instanceof Actor) { entity.onPostCollisionResolve(postcollision.target, postcollision.other, postcollision.side, postcollision.contact); @@ -215,7 +215,7 @@ export class ColliderComponent extends Component { */ useBoxCollider(width: number, height: number, anchor: Vector = Vector.Half, center: Vector = Vector.Zero): PolygonCollider { const collider = Shape.Box(width, height, anchor, center); - return (this.set(collider)); + return this.set(collider); } /** @@ -229,7 +229,7 @@ export class ColliderComponent extends Component { */ usePolygonCollider(points: Vector[], center: Vector = Vector.Zero): PolygonCollider { const poly = Shape.Polygon(points, center); - return (this.set(poly)); + return this.set(poly); } /** @@ -239,7 +239,7 @@ export class ColliderComponent extends Component { */ useCircleCollider(radius: number, center: Vector = Vector.Zero): CircleCollider { const collider = Shape.Circle(radius, center); - return (this.set(collider)); + return this.set(collider); } /** @@ -250,7 +250,7 @@ export class ColliderComponent extends Component { */ useEdgeCollider(begin: Vector, end: Vector): EdgeCollider { const collider = Shape.Edge(begin, end); - return (this.set(collider)); + return this.set(collider); } /** @@ -258,6 +258,6 @@ export class ColliderComponent extends Component { * @param colliders */ useCompositeCollider(colliders: Collider[]): CompositeCollider { - return (this.set(new CompositeCollider(colliders))); + return this.set(new CompositeCollider(colliders)); } } diff --git a/src/engine/Collision/Colliders/CircleCollider.ts b/src/engine/Collision/Colliders/CircleCollider.ts index ebfbd83c..f6e298b6 100644 --- a/src/engine/Collision/Colliders/CircleCollider.ts +++ b/src/engine/Collision/Colliders/CircleCollider.ts @@ -134,7 +134,8 @@ export class CircleCollider extends Collider { } satisfies RayCastHit; } return null; - } else { // two point + } else { + // two point const toi1 = -dir.dot(orig.sub(c)) + discriminant; const toi2 = -dir.dot(orig.sub(c)) - discriminant; @@ -149,7 +150,7 @@ export class CircleCollider extends Collider { const minToi = Math.min(...positiveToi); if (minToi <= max) { - const point = ray.getPoint(minToi); + const point = ray.getPoint(minToi); return { point, normal: point.sub(c).normalize(), @@ -213,13 +214,16 @@ export class CircleCollider extends Collider { const tx = this._transform; const scale = tx?.globalScale ?? Vector.One; const rotation = tx?.globalRotation ?? 0; - const pos = (tx?.globalPos ?? Vector.Zero); + const pos = tx?.globalPos ?? Vector.Zero; return new BoundingBox( this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius - ).rotate(rotation).scale(scale).translate(pos); + ) + .rotate(rotation) + .scale(scale) + .translate(pos); } /** @@ -275,12 +279,12 @@ export class CircleCollider extends Collider { const tx = this._transform; const scale = tx?.globalScale ?? Vector.One; const rotation = tx?.globalRotation ?? 0; - const pos = (tx?.globalPos ?? Vector.Zero); + const pos = tx?.globalPos ?? Vector.Zero; ex.save(); ex.translate(pos.x, pos.y); ex.rotate(rotation); ex.scale(scale.x, scale.y); - ex.drawCircle((this.offset ?? Vector.Zero), this._naturalRadius, Color.Transparent, color, lineWidth); + ex.drawCircle(this.offset ?? Vector.Zero, this._naturalRadius, Color.Transparent, color, lineWidth); ex.restore(); } } diff --git a/src/engine/Collision/Colliders/Collider.ts b/src/engine/Collision/Colliders/Collider.ts index 444cf1dc..9a2a411e 100644 --- a/src/engine/Collision/Colliders/Collider.ts +++ b/src/engine/Collision/Colliders/Collider.ts @@ -114,8 +114,7 @@ export abstract class Collider implements Clonable { */ abstract update(transform: Transform): void; - - abstract debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }): void; + abstract debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number; pointSize: number }): void; abstract clone(): Collider; } diff --git a/src/engine/Collision/Colliders/CompositeCollider.ts b/src/engine/Collision/Colliders/CompositeCollider.ts index f1bd397d..9dd91106 100644 --- a/src/engine/Collision/Colliders/CompositeCollider.ts +++ b/src/engine/Collision/Colliders/CompositeCollider.ts @@ -56,7 +56,7 @@ export class CompositeCollider extends Collider { let colliders: Collider[]; if (collider instanceof CompositeCollider) { colliders = collider.getColliders(); - colliders.forEach(c => c.offset.addEqual(collider.offset)); + colliders.forEach((c) => c.offset.addEqual(collider.offset)); } else { colliders = [collider]; } @@ -267,7 +267,7 @@ export class CompositeCollider extends Collider { } } - public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }) { + public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number; pointSize: number }) { const colliders = this.getColliders(); ex.save(); ex.translate(this.offset.x, this.offset.y); diff --git a/src/engine/Collision/Colliders/EdgeCollider.ts b/src/engine/Collision/Colliders/EdgeCollider.ts index 2f4a5e97..77a3b671 100644 --- a/src/engine/Collision/Colliders/EdgeCollider.ts +++ b/src/engine/Collision/Colliders/EdgeCollider.ts @@ -286,5 +286,4 @@ export class EdgeCollider extends Collider { ex.drawCircle(begin, 2, color); ex.drawCircle(end, 2, color); } - } diff --git a/src/engine/Collision/Colliders/PolygonCollider.ts b/src/engine/Collision/Colliders/PolygonCollider.ts index d235f930..8b9cca31 100644 --- a/src/engine/Collision/Colliders/PolygonCollider.ts +++ b/src/engine/Collision/Colliders/PolygonCollider.ts @@ -89,7 +89,8 @@ export class PolygonCollider extends Collider { if (!options.suppressConvexWarning) { this._logger.warn( 'Excalibur only supports convex polygon colliders and will not behave properly.' + - 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles'); + 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles' + ); } } @@ -160,7 +161,7 @@ export class PolygonCollider extends Collider { } polygons.push([this.points[0], this.points[1], this.points[2]]); - return new CompositeCollider(polygons.map(points => Shape.Polygon(points))); + return new CompositeCollider(polygons.map((points) => Shape.Polygon(points))); } /** @@ -213,7 +214,7 @@ export class PolygonCollider extends Collider { return true; } - const convexVertices = vertices.map((_,i) => isConvex(i)); + const convexVertices = vertices.map((_, i) => isConvex(i)); /** * Quick test for point in triangle @@ -250,7 +251,6 @@ export class PolygonCollider extends Collider { function findEarTip() { for (let i = 0; i < vertexCount; i++) { if (convexVertices[i]) { - const prev = getPrevIndex(i); const next = getNextIndex(i); @@ -325,8 +325,7 @@ export class PolygonCollider extends Collider { triangles.push([vertices[0], vertices[1], vertices[2]]); // FIXME: there is a colinear triangle that sneaks in here sometimes - return new CompositeCollider( - triangles.map(points => Shape.Polygon(points, Vector.Zero, true))); + return new CompositeCollider(triangles.map((points) => Shape.Polygon(points, Vector.Zero, true))); } /** @@ -640,13 +639,11 @@ export class PolygonCollider extends Collider { for (let i = 0; i < points.length; i++) { const iplusone = (i + 1) % points.length; const crossTerm = points[iplusone].cross(points[i]); - numerator += - crossTerm * - (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone])); + numerator += crossTerm * (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone])); denominator += crossTerm; } this._cachedMass = mass; - return this._cachedInertia = (mass / 6) * (numerator / denominator); + return (this._cachedInertia = (mass / 6) * (numerator / denominator)); } /** @@ -701,7 +698,7 @@ export class PolygonCollider extends Collider { return new Projection(min, max); } - public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }) { + public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number; pointSize: number }) { const points = this.getTransformedPoints(); Debug.drawPolygon(points, { color }); } diff --git a/src/engine/Collision/CollisionSystem.ts b/src/engine/Collision/CollisionSystem.ts index e87ca5f4..afd06617 100644 --- a/src/engine/Collision/CollisionSystem.ts +++ b/src/engine/Collision/CollisionSystem.ts @@ -30,20 +30,23 @@ export class CollisionSystem extends System { private _currentFrameContacts = new Map(); private get _processor(): DynamicTreeCollisionProcessor { return this._physics.collisionProcessor; - }; + } private _trackCollider: (c: Collider) => void; private _untrackCollider: (c: Collider) => void; - constructor(world: World, private _physics: PhysicsWorld) { + constructor( + world: World, + private _physics: PhysicsWorld + ) { super(); this._arcadeSolver = new ArcadeSolver(_physics.config.arcade); this._realisticSolver = new RealisticSolver(_physics.config.realistic); - this._physics.$configUpdate.subscribe(() => this._configDirty = true); + this._physics.$configUpdate.subscribe(() => (this._configDirty = true)); this._trackCollider = (c: Collider) => this._processor.track(c); this._untrackCollider = (c: Collider) => this._processor.untrack(c); this.query = world.query([TransformComponent, MotionComponent, ColliderComponent]); - this.query.entityAdded$.subscribe(e => { + this.query.entityAdded$.subscribe((e) => { const colliderComponent = e.get(ColliderComponent); colliderComponent.$colliderAdded.subscribe(this._trackCollider); colliderComponent.$colliderRemoved.subscribe(this._untrackCollider); @@ -52,7 +55,7 @@ export class CollisionSystem extends System { this._processor.track(collider); } }); - this.query.entityRemoved$.subscribe(e => { + this.query.entityRemoved$.subscribe((e) => { const colliderComponent = e.get(ColliderComponent); const collider = colliderComponent.get(); if (colliderComponent && collider) { diff --git a/src/engine/Collision/Detection/DynamicTree.ts b/src/engine/Collision/Detection/DynamicTree.ts index 9aad9908..b4fc8596 100644 --- a/src/engine/Collision/Detection/DynamicTree.ts +++ b/src/engine/Collision/Detection/DynamicTree.ts @@ -48,7 +48,8 @@ export class DynamicTree> { public nodes: { [key: number]: TreeNode }; constructor( private _config: Required['dynamicTree']>, - public worldBounds: BoundingBox = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)) { + public worldBounds: BoundingBox = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE) + ) { this.root = null; this.nodes = {}; } diff --git a/src/engine/Collision/Detection/Pair.ts b/src/engine/Collision/Detection/Pair.ts index 5b65ed86..55e1dbf1 100644 --- a/src/engine/Collision/Detection/Pair.ts +++ b/src/engine/Collision/Detection/Pair.ts @@ -9,7 +9,10 @@ import { Collider } from '../Colliders/Collider'; */ export class Pair { public id: string = null; - constructor(public colliderA: Collider, public colliderB: Collider) { + constructor( + public colliderA: Collider, + public colliderB: Collider + ) { this.id = Pair.calculatePairHash(colliderA.id, colliderB.id); } @@ -28,9 +31,7 @@ export class Pair { } // Colliders with the same owner do not collide (composite colliders) - if (colliderA.owner && - colliderB.owner && - colliderA.owner.id === colliderB.owner.id) { + if (colliderA.owner && colliderB.owner && colliderA.owner.id === colliderB.owner.id) { return false; } diff --git a/src/engine/Collision/Detection/QuadTree.ts b/src/engine/Collision/Detection/QuadTree.ts index 5d27d100..015a1a35 100644 --- a/src/engine/Collision/Detection/QuadTree.ts +++ b/src/engine/Collision/Detection/QuadTree.ts @@ -33,8 +33,11 @@ export class QuadTree { public bottomLeft: QuadTree | null = null; public bottomRight: QuadTree | null = null; - constructor(public bounds: BoundingBox, public options?: QuadTreeOptions) { - this.options = {...this._defaultOptions, ...options}; + constructor( + public bounds: BoundingBox, + public options?: QuadTreeOptions + ) { + this.options = { ...this._defaultOptions, ...options }; this.halfWidth = bounds.width / 2; this.halfHeight = bounds.height / 2; } @@ -55,27 +58,36 @@ export class QuadTree { top: this.bounds.top, right: this.bounds.left + this.halfWidth, bottom: this.bounds.top + this.halfHeight - }), newLevelOptions); + }), + newLevelOptions + ); this.topRight = new QuadTree( new BoundingBox({ left: this.bounds.left + this.halfWidth, top: this.bounds.top, right: this.bounds.right, bottom: this.bounds.top + this.halfHeight - }), newLevelOptions); - this.bottomLeft = new QuadTree(new BoundingBox({ - left: this.bounds.left, - top: this.bounds.top + this.halfHeight, - right: this.bounds.left + this.halfWidth, - bottom: this.bounds.bottom - }), newLevelOptions); + }), + newLevelOptions + ); + this.bottomLeft = new QuadTree( + new BoundingBox({ + left: this.bounds.left, + top: this.bounds.top + this.halfHeight, + right: this.bounds.left + this.halfWidth, + bottom: this.bounds.bottom + }), + newLevelOptions + ); this.bottomRight = new QuadTree( new BoundingBox({ left: this.bounds.left + this.halfWidth, top: this.bounds.top + this.halfHeight, right: this.bounds.right, bottom: this.bounds.bottom - }), newLevelOptions); + }), + newLevelOptions + ); } private _insertIntoSubNodes(item: TItem) { @@ -107,7 +119,6 @@ export class QuadTree { return; } - // leaf case this.items.push(item); @@ -165,7 +176,6 @@ export class QuadTree { * @returns items */ query(boundingBox: BoundingBox): TItem[] { - let results = this.items; if (this._isDivided) { @@ -222,11 +232,9 @@ export class QuadTree { return 0; } - return 1 + Math.max( - this.topLeft.getTreeDepth(), - this.topRight.getTreeDepth(), - this.bottomLeft.getTreeDepth(), - this.bottomRight.getTreeDepth() + return ( + 1 + + Math.max(this.topLeft.getTreeDepth(), this.topRight.getTreeDepth(), this.bottomLeft.getTreeDepth(), this.bottomRight.getTreeDepth()) ); } @@ -239,4 +247,4 @@ export class QuadTree { this.bottomRight.bounds.draw(ctx, Color.Yellow); } } -} \ No newline at end of file +} diff --git a/src/engine/Collision/Detection/RayCastHit.ts b/src/engine/Collision/Detection/RayCastHit.ts index d0dd0fab..89979abe 100644 --- a/src/engine/Collision/Detection/RayCastHit.ts +++ b/src/engine/Collision/Detection/RayCastHit.ts @@ -2,7 +2,6 @@ import { Vector } from '../../Math/vector'; import { Collider } from '../Colliders/Collider'; import { BodyComponent } from '../BodyComponent'; - export interface RayCastHit { /** * The distance along the ray cast in pixels that a hit was detected diff --git a/src/engine/Collision/Group/CollisionGroup.ts b/src/engine/Collision/Group/CollisionGroup.ts index a0c1fde4..31853ff3 100644 --- a/src/engine/Collision/Group/CollisionGroup.ts +++ b/src/engine/Collision/Group/CollisionGroup.ts @@ -97,7 +97,7 @@ export class CollisionGroup { public canCollide(other: CollisionGroup): boolean { const overlap1 = this.category & other.mask; const overlap2 = this.mask & other.category; - return (overlap1 !== 0) && (overlap2 !== 0); + return overlap1 !== 0 && overlap2 !== 0; } /** @@ -136,7 +136,7 @@ export class CollisionGroup { public toString() { return ` category: ${this.category.toString(2).padStart(32, '0')} -mask: ${(this.mask>>>0).toString(2).padStart(32, '0')} +mask: ${(this.mask >>> 0).toString(2).padStart(32, '0')} `; } } diff --git a/src/engine/Collision/MotionSystem.ts b/src/engine/Collision/MotionSystem.ts index 2379ef2e..faa67b57 100644 --- a/src/engine/Collision/MotionSystem.ts +++ b/src/engine/Collision/MotionSystem.ts @@ -12,9 +12,12 @@ export class MotionSystem extends System { public priority = SystemPriority.Higher; private _physicsConfigDirty = false; query: Query; - constructor(public world: World, public physics: PhysicsWorld) { + constructor( + public world: World, + public physics: PhysicsWorld + ) { super(); - physics.$configUpdate.subscribe(() => this._physicsConfigDirty = true); + physics.$configUpdate.subscribe(() => (this._physicsConfigDirty = true)); this.query = this.world.query([TransformComponent, MotionComponent]); } diff --git a/src/engine/Collision/PhysicsConfig.ts b/src/engine/Collision/PhysicsConfig.ts index 1488198f..0068195e 100644 --- a/src/engine/Collision/PhysicsConfig.ts +++ b/src/engine/Collision/PhysicsConfig.ts @@ -4,7 +4,6 @@ import { SolverStrategy } from './SolverStrategy'; import { Physics } from './Physics'; import { ContactSolveBias } from './Solver/ContactBias'; - export interface PhysicsConfig { /** * Excalibur physics simulation is enabled @@ -46,14 +45,13 @@ export interface PhysicsConfig { * * Default is 'together' if unset */ - compositeStrategy?: 'separate' | 'together' - } + compositeStrategy?: 'separate' | 'together'; + }; /** * Configure excalibur continuous collision (WIP) */ continuous?: { - /** * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent * bodies from tunneling through one another. @@ -77,7 +75,7 @@ export interface PhysicsConfig { * Default 0.1 */ surfaceEpsilon?: number; - } + }; /** * Configure body defaults @@ -117,7 +115,7 @@ export interface PhysicsConfig { * Default false */ canSleepByDefault?: boolean; - } + }; /** * Configure the dynamic tree spatial data structure for locating pairs and raycasts @@ -136,7 +134,7 @@ export interface PhysicsConfig { * Default 2 */ velocityMultiplier?: number; - } + }; /** * Configure the [[ArcadeSolver]] @@ -153,7 +151,7 @@ export interface PhysicsConfig { * * By default [[ContactSolveBias.None]] which sorts by distance */ contactSolveBias?: ContactSolveBias; - } + }; /** * Configure the [[RealisticSolver]] @@ -195,7 +193,7 @@ export interface PhysicsConfig { * Default true */ warmStart?: boolean; - } + }; } export const DefaultPhysicsConfig: DeepRequired = { @@ -271,4 +269,4 @@ export function DeprecatedStaticToConfig(): DeepRequired { warmStart: Physics.warmStart } }; -} \ No newline at end of file +} diff --git a/src/engine/Collision/PhysicsWorld.ts b/src/engine/Collision/PhysicsWorld.ts index 127c036b..bfad3037 100644 --- a/src/engine/Collision/PhysicsWorld.ts +++ b/src/engine/Collision/PhysicsWorld.ts @@ -7,13 +7,12 @@ import { PhysicsConfig } from './PhysicsConfig'; import { watchDeep } from '../Util/Watch'; export class PhysicsWorld { - - $configUpdate = new Observable>; + $configUpdate = new Observable>(); private _configDirty = false; private _config: DeepRequired; get config(): DeepRequired { - return watchDeep(this._config, change => { + return watchDeep(this._config, (change) => { this.$configUpdate.notifyAll(change); }); } @@ -55,4 +54,4 @@ export class PhysicsWorld { public rayCast(ray: Ray, options?: RayCastOptions): RayCastHit[] { return this.collisionProcessor.rayCast(ray, options); } -} \ No newline at end of file +} diff --git a/src/engine/Collision/Solver/ArcadeSolver.ts b/src/engine/Collision/Solver/ArcadeSolver.ts index a115f661..77a88c48 100644 --- a/src/engine/Collision/Solver/ArcadeSolver.ts +++ b/src/engine/Collision/Solver/ArcadeSolver.ts @@ -26,7 +26,7 @@ export class ArcadeSolver implements CollisionSolver { this.preSolve(contacts); // Remove any canceled contacts - contacts = contacts.filter(c => !c.isCanceled()); + contacts = contacts.filter((c) => !c.isCanceled()); // Locate collision bias order let bias: ContactBias; @@ -52,7 +52,7 @@ export class ArcadeSolver implements CollisionSolver { const bDir = this.directionMap.get(b.id); const aDist = this.distanceMap.get(a.id); const bDist = this.distanceMap.get(b.id); - return (bias[aDir] - bias[bDir]) || (aDist - bDist); + return bias[aDir] - bias[bDir] || aDist - bDist; }); for (const contact of contacts) { @@ -70,7 +70,7 @@ export class ArcadeSolver implements CollisionSolver { } public preSolve(contacts: CollisionContact[]) { - const epsilon = .0001; + const epsilon = 0.0001; for (const contact of contacts) { if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) { // Cancel near 0 mtv collisions @@ -86,9 +86,7 @@ export class ArcadeSolver implements CollisionSolver { this.directionMap.set(contact.id, side === Side.Left || side === Side.Right ? 'horizontal' : 'vertical'); // Publish collision events on both participants - contact.colliderA.events.emit( - 'precollision', - new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact)); + contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact)); contact.colliderB.events.emit( 'precollision', new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact) @@ -114,9 +112,7 @@ export class ArcadeSolver implements CollisionSolver { const side = Side.fromDirection(contact.mtv); const mtv = contact.mtv.negate(); // Publish collision events on both participants - contact.colliderA.events.emit( - 'postcollision', - new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact)); + contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact)); contact.colliderB.events.emit( 'postcollision', new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact) @@ -125,7 +121,7 @@ export class ArcadeSolver implements CollisionSolver { } public solvePosition(contact: CollisionContact) { - const epsilon = .0001; + const epsilon = 0.0001; // if bounds no longer intersect skip to the next // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) { @@ -170,7 +166,6 @@ export class ArcadeSolver implements CollisionSolver { } } - public solveVelocity(contact: CollisionContact) { if (contact.isCanceled()) { return; @@ -182,7 +177,6 @@ export class ArcadeSolver implements CollisionSolver { const bodyB = colliderB.owner?.get(BodyComponent); if (bodyA && bodyB) { - if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) { return; } diff --git a/src/engine/Collision/Solver/ContactBias.ts b/src/engine/Collision/Solver/ContactBias.ts index d8049d3b..8dc8d314 100644 --- a/src/engine/Collision/Solver/ContactBias.ts +++ b/src/engine/Collision/Solver/ContactBias.ts @@ -1,4 +1,3 @@ - /** * Tells the Arcade collision solver to prefer certain contacts over others */ @@ -20,22 +19,22 @@ export interface ContactBias { * Vertical First contact solve bias Used by the [[ArcadeSolver]] to sort contacts */ export const VerticalFirst: ContactBias = { - 'vertical': 1, - 'horizontal': 2 + vertical: 1, + horizontal: 2 } as const; /** * Horizontal First contact solve bias Used by the [[ArcadeSolver]] to sort contacts */ export const HorizontalFirst: ContactBias = { - 'horizontal': 1, - 'vertical': 2 + horizontal: 1, + vertical: 2 } as const; /** * None value, [[ArcadeSolver]] sorts contacts using distance by default */ export const None: ContactBias = { - 'horizontal': 0, - 'vertical': 0 -} as const; \ No newline at end of file + horizontal: 0, + vertical: 0 +} as const; diff --git a/src/engine/Collision/Solver/ContactConstraintPoint.ts b/src/engine/Collision/Solver/ContactConstraintPoint.ts index ec1a5a4f..c111e383 100644 --- a/src/engine/Collision/Solver/ContactConstraintPoint.ts +++ b/src/engine/Collision/Solver/ContactConstraintPoint.ts @@ -6,7 +6,11 @@ import { CollisionContact } from '../Detection/CollisionContact'; * Holds information about contact points, meant to be reused over multiple frames of contact */ export class ContactConstraintPoint { - constructor(public point: Vector, public local: Vector, public contact: CollisionContact) { + constructor( + public point: Vector, + public local: Vector, + public contact: CollisionContact + ) { this.update(); } diff --git a/src/engine/Collision/Solver/RealisticSolver.ts b/src/engine/Collision/Solver/RealisticSolver.ts index 60b8401b..b12b7091 100644 --- a/src/engine/Collision/Solver/RealisticSolver.ts +++ b/src/engine/Collision/Solver/RealisticSolver.ts @@ -26,7 +26,7 @@ export class RealisticSolver implements CollisionSolver { this.preSolve(contacts); // Remove any canceled contacts - contacts = contacts.filter(c => !c.isCanceled()); + contacts = contacts.filter((c) => !c.isCanceled()); // Solve velocity first this.solveVelocity(contacts); @@ -41,7 +41,7 @@ export class RealisticSolver implements CollisionSolver { } preSolve(contacts: CollisionContact[]) { - const epsilon = .0001; + const epsilon = 0.0001; for (const contact of contacts) { if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) { // Cancel near 0 mtv collisions @@ -52,7 +52,8 @@ export class RealisticSolver implements CollisionSolver { const side = Side.fromDirection(contact.mtv); contact.colliderA.events.emit( 'precollision', - new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact)); + new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) + ); contact.colliderA.events.emit( 'beforecollisionresolve', new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) as any @@ -128,7 +129,8 @@ export class RealisticSolver implements CollisionSolver { const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness; const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity()); contactPoints[pointIndex].originalVelocityAndRestitution = 0; - if (relativeVelocity < -0.1) { // TODO what's a good threshold here? + if (relativeVelocity < -0.1) { + // TODO what's a good threshold here? contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity; } pointIndex++; diff --git a/src/engine/Collision/Solver/Solver.ts b/src/engine/Collision/Solver/Solver.ts index 817dd9ce..f9dae8e3 100644 --- a/src/engine/Collision/Solver/Solver.ts +++ b/src/engine/Collision/Solver/Solver.ts @@ -51,5 +51,5 @@ export interface CollisionSolver { * 4. postSolve * @param contacts */ - solve(contacts: CollisionContact[]): CollisionContact[] -} \ No newline at end of file + solve(contacts: CollisionContact[]): CollisionContact[]; +} diff --git a/src/engine/Color.ts b/src/engine/Color.ts index 6c44e81b..2df0eeb6 100644 --- a/src/engine/Color.ts +++ b/src/engine/Color.ts @@ -1,4 +1,3 @@ - /** * Provides standard colors (e.g. [[Color.Black]]) * but you can also create custom colors using RGB, HSL, or Hex. Also provides @@ -418,7 +417,12 @@ export class Color { * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c */ class HSLColor { - constructor(public h: number, public s: number, public l: number, public a: number) { } + constructor( + public h: number, + public s: number, + public l: number, + public a: number + ) {} public static hue2rgb(p: number, q: number, t: number): number { if (t < 0) { diff --git a/src/engine/Configurable.ts b/src/engine/Configurable.ts index 86a1cb8f..b4d81ae8 100644 --- a/src/engine/Configurable.ts +++ b/src/engine/Configurable.ts @@ -24,7 +24,7 @@ export function Configurable>(base: T): T { super(...args); //get the number of arguments that aren't undefined. TS passes a value to all parameters //of whatever ctor is the implementation, so args.length doesn't work here. - const size = args.filter(function(value) { + const size = args.filter(function (value) { return value !== undefined; }).length; if (size === 1 && args[0] && typeof args[0] === 'object' && !(args[0] instanceof Array)) { diff --git a/src/engine/Context.ts b/src/engine/Context.ts index c05bddf7..55c0a8d8 100644 --- a/src/engine/Context.ts +++ b/src/engine/Context.ts @@ -8,7 +8,6 @@ export interface Context { value: TValue; } - /** * Creates a injectable context that can be retrieved later with `useContext(context)` * @@ -38,4 +37,4 @@ export function createContext() { */ export function useContext(context: Context): TValue { return context.value; -} \ No newline at end of file +} diff --git a/src/engine/Debug/DebugConfig.ts b/src/engine/Debug/DebugConfig.ts index 0e0e5b0b..3e65e019 100644 --- a/src/engine/Debug/DebugConfig.ts +++ b/src/engine/Debug/DebugConfig.ts @@ -294,7 +294,7 @@ export class DebugConfig { showGeometry: true, geometryColor: Color.Green, geometryLineWidth: 1, - geometryPointSize: .5 + geometryPointSize: 0.5 }; /** @@ -356,7 +356,7 @@ export class DebugConfig { showGrid: false, gridColor: Color.Red, - gridWidth: .5, + gridWidth: 0.5, showSolidBounds: false, solidBoundsColor: Color.fromHex('#8080807F'), // grayish showColliderGeometry: true diff --git a/src/engine/Debug/DebugSystem.ts b/src/engine/Debug/DebugSystem.ts index c61642a3..2208db53 100644 --- a/src/engine/Debug/DebugSystem.ts +++ b/src/engine/Debug/DebugSystem.ts @@ -10,7 +10,7 @@ import { vec, Vector } from '../Math/vector'; import { toDegrees } from '../Math/util'; import { BodyComponent } from '../Collision/BodyComponent'; import { CollisionSystem } from '../Collision/CollisionSystem'; -import { CompositeCollider } from '../Collision/Colliders/CompositeCollider'; +import { CompositeCollider } from '../Collision/Colliders/CompositeCollider'; import { GraphicsComponent } from '../Graphics/GraphicsComponent'; import { Particle } from '../Particles'; import { DebugGraphicsComponent } from '../Graphics/DebugGraphicsComponent'; @@ -189,7 +189,7 @@ export class DebugSystem extends System { } if (bodySettings.showAll || bodySettings.showSleeping) { - this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping: 'cant sleep'})`, cursor); + this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping : 'cant sleep'})`, cursor); cursor = cursor.add(lineHeight); } } diff --git a/src/engine/Director/CrossFade.ts b/src/engine/Director/CrossFade.ts index 1acca790..351172aa 100644 --- a/src/engine/Director/CrossFade.ts +++ b/src/engine/Director/CrossFade.ts @@ -18,7 +18,7 @@ export class CrossFade extends Transition { image: HTMLImageElement; screenCover: Sprite; constructor(options: TransitionOptions & CrossFadeOptions) { - super({direction: 'in', ...options}); // default the correct direction + super({ direction: 'in', ...options }); // default the correct direction this.name = `CrossFade#${this.id}`; } @@ -53,4 +53,4 @@ export class CrossFade extends Transition { override onUpdate(progress: number): void { this.graphics.opacity = progress; } -} \ No newline at end of file +} diff --git a/src/engine/Director/DefaultLoader.ts b/src/engine/Director/DefaultLoader.ts index 555e822b..97caff13 100644 --- a/src/engine/Director/DefaultLoader.ts +++ b/src/engine/Director/DefaultLoader.ts @@ -19,12 +19,12 @@ export interface DefaultLoaderOptions { export type LoaderEvents = { // Add event types here - beforeload: void, - afterload: void, - useraction: void, - loadresourcestart: Loadable, - loadresourceend: Loadable, -} + beforeload: void; + afterload: void; + useraction: void; + loadresourcestart: Loadable; + loadresourceend: Loadable; +}; export const LoaderEvents = { // Add event types here @@ -59,7 +59,6 @@ export class DefaultLoader implements Loadable[]> { private _numLoaded: number = 0; public engine: Engine; - /** * @param options Optionally provide the list of resources you want to load at constructor time */ @@ -87,7 +86,6 @@ export class DefaultLoader implements Loadable[]> { * */ public async onUserAction(): Promise { - return await Promise.resolve(); } @@ -173,7 +171,7 @@ export class DefaultLoader implements Loadable[]> { ctx.strokeStyle = 'white'; ctx.lineWidth = 10; ctx.lineCap = 'round'; - ctx.arc(0, 0, 40, speed, speed + (Math.PI * 3 / 2)); + ctx.arc(0, 0, 40, speed, speed + (Math.PI * 3) / 2); ctx.stroke(); ctx.fillStyle = 'white'; @@ -186,7 +184,6 @@ export class DefaultLoader implements Loadable[]> { ctx.restore(); } - private _loadingFuture = new Future(); public areResourcesLoaded() { return this._loadingFuture.promise; diff --git a/src/engine/Director/Director.ts b/src/engine/Director/Director.ts index 6f14f134..9c48d0a3 100644 --- a/src/engine/Director/Director.ts +++ b/src/engine/Director/Director.ts @@ -15,10 +15,10 @@ export interface DirectorNavigationEvent { } export type DirectorEvents = { - navigationstart: DirectorNavigationEvent, - navigation: DirectorNavigationEvent, - navigationend: DirectorNavigationEvent, -} + navigationstart: DirectorNavigationEvent; + navigation: DirectorNavigationEvent; + navigationend: DirectorNavigationEvent; +}; export const DirectorEvents = { NavigationStart: 'navigationstart', @@ -64,10 +64,9 @@ export interface StartOptions { /** * Optionally provide a main loader to run before the game starts */ - loader?: DefaultLoader | LoaderConstructor + loader?: DefaultLoader | LoaderConstructor; } - /** * Provide scene activation data and override any existing configured route transitions or loaders */ @@ -137,7 +136,7 @@ export class Director { public readonly rootScene: Scene; private _sceneToLoader = new Map(); - private _sceneToTransition = new Map(); + private _sceneToTransition = new Map(); /** * Used to keep track of scenes that have already been loaded so we don't load multiple times */ @@ -154,7 +153,10 @@ export class Director { return this._isTransitioning; } - constructor(private _engine: Engine, scenes: SceneMap) { + constructor( + private _engine: Engine, + scenes: SceneMap + ) { this.rootScene = this.currentScene = new Scene(); this.add('root', this.rootScene); this.currentScene = this.rootScene; @@ -308,10 +310,10 @@ export class Director { * @param sceneOrRoute */ add(name: TScene, sceneOrRoute: Scene | SceneConstructor | SceneWithOptions): Director { - if (!(sceneOrRoute instanceof Scene) && !(isSceneConstructor(sceneOrRoute))) { + if (!(sceneOrRoute instanceof Scene) && !isSceneConstructor(sceneOrRoute)) { const { loader, transitions } = sceneOrRoute; - const {in: inTransition, out: outTransition } = transitions ?? {}; - this._sceneToTransition.set(name, {in: inTransition, out: outTransition}); + const { in: inTransition, out: outTransition } = transitions ?? {}; + this._sceneToTransition.set(name, { in: inTransition, out: outTransition }); if (isLoaderConstructor(loader)) { this._sceneToLoader.set(name, new loader()); @@ -331,7 +333,6 @@ export class Director { remove(sceneCtor: SceneConstructor): void; remove(name: WithRoot): void; remove(nameOrScene: TKnownScenes | Scene | SceneConstructor | string) { - if (nameOrScene instanceof Scene || isSceneConstructor(nameOrScene)) { const sceneOrCtor = nameOrScene; // remove scene @@ -377,7 +378,6 @@ export class Director { * @param options */ async goto(destinationScene: TKnownScenes | string, options?: GoToOptions) { - const maybeDest = this.getSceneInstance(destinationScene); if (!maybeDest) { this._logger.warn(`Scene ${destinationScene} does not exist! Check the name, are you sure you added it?`); @@ -393,10 +393,11 @@ export class Director { options = { // Engine configuration then dynamic scene transitions - ...{ sourceOut: this._getOutTransition(this.currentSceneName) ?? maybeSourceOut}, - ...{ destinationIn: this._getInTransition(destinationScene) ?? maybeDestinationIn}, + ...{ sourceOut: this._getOutTransition(this.currentSceneName) ?? maybeSourceOut }, + ...{ destinationIn: this._getInTransition(destinationScene) ?? maybeDestinationIn }, // Goto options - ...options }; + ...options + }; const { sourceOut, destinationIn, sceneActivationData } = options; @@ -565,5 +566,3 @@ export class Director { } as DirectorNavigationEvent); } } - - diff --git a/src/engine/Director/FadeInOut.ts b/src/engine/Director/FadeInOut.ts index d1c00284..34ae6b1c 100644 --- a/src/engine/Director/FadeInOut.ts +++ b/src/engine/Director/FadeInOut.ts @@ -46,4 +46,4 @@ export class FadeInOut extends Transition { override onUpdate(progress: number): void { this.graphics.opacity = progress; } -} \ No newline at end of file +} diff --git a/src/engine/Director/Loader.css b/src/engine/Director/Loader.css index d1117883..e3157a2f 100644 --- a/src/engine/Director/Loader.css +++ b/src/engine/Director/Loader.css @@ -20,7 +20,9 @@ button#excalibur-play { line-height: 1; cursor: pointer; text-align: center; - transition: background 250ms ease-in-out, transform 150ms ease; + transition: + background 250ms ease-in-out, + transform 150ms ease; -webkit-appearance: none; -moz-appearance: none; diff --git a/src/engine/Director/Loader.ts b/src/engine/Director/Loader.ts index d432c6a0..8c03e027 100644 --- a/src/engine/Director/Loader.ts +++ b/src/engine/Director/Loader.ts @@ -96,7 +96,7 @@ export class Loader extends DefaultLoader { fullscreenAfterLoad: false, fullscreenContainer: undefined }; - private _originalOptions: LoaderOptions = {loadables:[]}; + private _originalOptions: LoaderOptions = { loadables: [] }; public events = new EventEmitter(); public screen: Screen; private _playButtonShown: boolean = false; @@ -209,9 +209,11 @@ export class Loader extends DefaultLoader { */ constructor(loadables?: Loadable[]); constructor(loadablesOrOptions?: Loadable[] | LoaderOptions) { - const options = Array.isArray(loadablesOrOptions) ? { - loadables: loadablesOrOptions - } : loadablesOrOptions; + const options = Array.isArray(loadablesOrOptions) + ? { + loadables: loadablesOrOptions + } + : loadablesOrOptions; super(options); this._originalOptions = { ...Loader._DEFAULT_LOADER_OPTIONS, ...options }; } @@ -241,7 +243,7 @@ export class Loader extends DefaultLoader { this._positionPlayButton(); } catch { // swallow if can't position - }; + } }; if (this.engine?.browser) { this.engine.browser.window.on('resize', resizeHandler); @@ -254,8 +256,8 @@ export class Loader extends DefaultLoader { } }); this._positionPlayButton(); - const playButtonClicked = new Promise(resolve => { - const startButtonHandler = (e: Event) => { + const playButtonClicked = new Promise((resolve) => { + const startButtonHandler = (e: Event) => { // We want to stop propagation to keep bubbling to the engine pointer handlers e.stopPropagation(); // Hide Button after click @@ -334,12 +336,7 @@ export class Loader extends DefaultLoader { private _positionPlayButton() { if (this.engine) { - const { - x: left, - y: top, - width: screenWidth, - height: screenHeight - } = this.engine.canvas.getBoundingClientRect(); + const { x: left, y: top, width: screenWidth, height: screenHeight } = this.engine.canvas.getBoundingClientRect(); if (this._playButtonRootElement) { const buttonWidth = this._playButton.clientWidth; const buttonHeight = this._playButton.clientHeight; diff --git a/src/engine/Director/Transition.ts b/src/engine/Director/Transition.ts index fe1fc881..e7d75577 100644 --- a/src/engine/Director/Transition.ts +++ b/src/engine/Director/Transition.ts @@ -204,7 +204,7 @@ export class Transition extends Entity { const currentScene = targetScene ?? engine.currentScene; currentScene.add(this); const self = this; - return coroutine(engine, function * () { + return coroutine(engine, function* () { while (!self.complete) { const elapsed = yield; // per frame self.updateTransition(engine, elapsed); @@ -233,4 +233,4 @@ export class Transition extends Entity { this._completeFuture.resolve(); } } -} \ No newline at end of file +} diff --git a/src/engine/Director/index.ts b/src/engine/Director/index.ts index 938301f2..a18f95ca 100644 --- a/src/engine/Director/index.ts +++ b/src/engine/Director/index.ts @@ -1,7 +1,6 @@ - export * from './Transition'; export * from './FadeInOut'; export * from './CrossFade'; export * from './Director'; export * from './Loader'; -export * from './DefaultLoader'; \ No newline at end of file +export * from './DefaultLoader'; diff --git a/src/engine/Engine.ts b/src/engine/Engine.ts index 04bb36ad..07dd3921 100644 --- a/src/engine/Engine.ts +++ b/src/engine/Engine.ts @@ -55,19 +55,19 @@ import { DeepRequired } from './Util/Required'; import { Context, createContext, useContext } from './Context'; export type EngineEvents = { - fallbackgraphicscontext: ExcaliburGraphicsContext2DCanvas, - initialize: InitializeEvent, - visible: VisibleEvent, - hidden: HiddenEvent, - start: GameStartEvent, - stop: GameStopEvent, - preupdate: PreUpdateEvent, - postupdate: PostUpdateEvent, - preframe: PreFrameEvent, - postframe: PostFrameEvent, - predraw: PreDrawEvent, - postdraw: PostDrawEvent, -} + fallbackgraphicscontext: ExcaliburGraphicsContext2DCanvas; + initialize: InitializeEvent; + visible: VisibleEvent; + hidden: HiddenEvent; + start: GameStartEvent; + stop: GameStopEvent; + preupdate: PreUpdateEvent; + postupdate: PostUpdateEvent; + preframe: PreFrameEvent; + postframe: PostFrameEvent; + predraw: PreDrawEvent; + postdraw: PostDrawEvent; +}; export const EngineEvents = { FallbackGraphicsContext: 'fallbackgraphicscontext', @@ -84,8 +84,6 @@ export const EngineEvents = { PostDraw: 'postdraw' } as const; - - /** * Enum representing the different mousewheel event bubble prevention */ @@ -143,7 +141,7 @@ export interface EngineOptions { * It is recommended you stick to `true` or `false` unless you understand what you're doing and need to control rendering to * a high degree. */ - antialiasing?: boolean | AntialiasOptions + antialiasing?: boolean | AntialiasOptions; /** * Quick convenience property to configure Excalibur to use special settings for "pretty" anti-aliased pixel art @@ -327,8 +325,8 @@ export interface EngineOptions { * In this example of the default if excalibur is running at 20fps or less for 100 frames it will trigger the fallback to the 2D * Canvas renderer. */ - threshold?: { numberOfFrames: number, fps: number }; - }, + threshold?: { numberOfFrames: number; fps: number }; + }; /** * Optionally configure the physics simulation in excalibur @@ -337,14 +335,14 @@ export interface EngineOptions { * * Default is configured to use [[SolverStrategy.Arcade]] physics simulation */ - physics?: boolean | PhysicsConfig + physics?: boolean | PhysicsConfig; /** * Optionally specify scenes with their transitions and loaders to excalibur's scene [[Director]] * * Scene transitions can can overridden dynamically by the `Scene` or by the call to `.goToScene` */ - scenes?: SceneMap + scenes?: SceneMap; } /** @@ -550,7 +548,6 @@ export class Engine implements CanInitialize, return this.director.currentScene; } - /** * The current [[Scene]] being drawn and updated on screen */ @@ -570,7 +567,7 @@ export class Engine implements CanInitialize, */ public get scenes(): { [key: string]: Scene | SceneConstructor | SceneWithOptions } { return this.director.scenes; - }; + } /** * Indicates whether the engine is set to fullscreen or not @@ -622,11 +619,11 @@ export class Engine implements CanInitialize, */ public get snapToPixel(): boolean { return this.graphicsContext.snapToPixel; - }; + } public set snapToPixel(shouldSnapToPixel: boolean) { this.graphicsContext.snapToPixel = shouldSnapToPixel; - }; + } /** * The action to take when a fatal exception is thrown @@ -778,10 +775,12 @@ export class Engine implements CanInitialize, 'background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;' ); // eslint-disable-next-line no-console - console.log('\n\ + console.log( + '\n\ /| ________________\n\ O|===|* >________________>\n\ - \\|'); + \\|' + ); // eslint-disable-next-line no-console console.log('Visit', 'http://excaliburjs.com', 'for more information'); } @@ -806,7 +805,7 @@ O|===|* >________________>\n\ this._logger.debug('Using Canvas element specified: ' + options.canvasElementId); //test for existence of element - if (document.getElementById(options.canvasElementId) === null) { + if (document.getElementById(options.canvasElementId) === null) { throw new Error('Cannot find existing element in the DOM, please ensure element is created prior to engine creation.'); } @@ -839,17 +838,10 @@ O|===|* >________________>\n\ let filtering: ImageFiltering; let multiSampleAntialiasing: boolean | { samples: number }; if (typeof options.antialiasing === 'object') { - ({ - pixelArtSampler, - nativeContextAntialiasing, - multiSampleAntialiasing, - filtering, - canvasImageRendering - } = { + ({ pixelArtSampler, nativeContextAntialiasing, multiSampleAntialiasing, filtering, canvasImageRendering } = { ...(options.pixelArt ? DefaultPixelArtOptions : DefaultAntialiasOptions), ...options.antialiasing }); - } else { pixelArtSampler = !!options.pixelArt; nativeContextAntialiasing = false; @@ -859,12 +851,14 @@ O|===|* >________________>\n\ } if (nativeContextAntialiasing && multiSampleAntialiasing) { - this._logger.warnOnce(`Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` + - ` at the same time, they are incompatible settings. If you aren\'t sure use multiSampleAntialiasing`); + this._logger.warnOnce( + `Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` + + ` at the same time, they are incompatible settings. If you aren\'t sure use multiSampleAntialiasing` + ); } if (options.pixelArt) { - uvPadding = .25; + uvPadding = 0.25; } if (!options.antialiasing || filtering === ImageFiltering.Pixel) { @@ -896,8 +890,8 @@ O|===|* >________________>\n\ } catch (e) { this._logger.warn( `Excalibur could not load webgl for some reason (${(e as Error).message}) and loaded a Canvas 2D fallback. ` + - `Some features of Excalibur will not work in this mode. \n\n` + - 'Read more about this issue at https://excaliburjs.com/docs/performance' + `Some features of Excalibur will not work in this mode. \n\n` + + 'Read more about this issue at https://excaliburjs.com/docs/performance' ); // fallback to canvas in case of failure useCanvasGraphicsContext = true; @@ -924,7 +918,7 @@ O|===|* >________________>\n\ viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA), resolution: options.resolution, displayMode, - pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null) + pixelRatio: options.suppressHiDPIScaling ? 1 : options.pixelRatio ?? null }); // TODO REMOVE STATIC!!! @@ -959,7 +953,7 @@ O|===|* >________________>\n\ this.physics = { ...DefaultPhysicsConfig, ...DeprecatedStaticToConfig(), - ...options.physics as DeepRequired + ...(options.physics as DeepRequired) }; } @@ -1044,22 +1038,22 @@ O|===|* >________________>\n\ this._performanceThresholdTriggered = true; this._logger.warn( `Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\n` + - 'this might mean your browser doesn\'t have webgl enabled or hardware acceleration is unavailable.\n\n' + - 'If in Chrome:\n' + - ' * Visit Settings > Advanced > System, and ensure "Use Hardware Acceleration" is checked.\n'+ - ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure "Override software rendering list" is "enabled"\n' + - 'If in Firefox, visit about:config\n' + - ' * Ensure webgl.disabled = false\n' + - ' * Ensure webgl.force-enabled = true\n' + - ' * Ensure layers.acceleration.force-enabled = true\n\n' + - 'Read more about this issue at https://excaliburjs.com/docs/performance' + "this might mean your browser doesn't have webgl enabled or hardware acceleration is unavailable.\n\n" + + 'If in Chrome:\n' + + ' * Visit Settings > Advanced > System, and ensure "Use Hardware Acceleration" is checked.\n' + + ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure "Override software rendering list" is "enabled"\n' + + 'If in Firefox, visit about:config\n' + + ' * Ensure webgl.disabled = false\n' + + ' * Ensure webgl.force-enabled = true\n' + + ' * Ensure layers.acceleration.force-enabled = true\n\n' + + 'Read more about this issue at https://excaliburjs.com/docs/performance' ); if (showPlayerMessage) { this._toaster.toast( - 'Excalibur is encountering performance issues. '+ - 'It\'s possible that your browser doesn\'t have hardware acceleration enabled. ' + - 'Visit [LINK] for more information and potential solutions.', + 'Excalibur is encountering performance issues. ' + + "It's possible that your browser doesn't have hardware acceleration enabled. " + + 'Visit [LINK] for more information and potential solutions.', 'https://excaliburjs.com/docs/performance' ); } @@ -1106,7 +1100,7 @@ O|===|* >________________>\n\ viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA), resolution: options.resolution, displayMode, - pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null) + pixelRatio: options.suppressHiDPIScaling ? 1 : options.pixelRatio ?? null }); this.screen.setCurrentCamera(this.currentScene.camera); @@ -1622,8 +1616,6 @@ O|===|* >________________>\n\ return this._isReadyFuture.promise; } - - /** * Starts the internal game loop for Excalibur after loading * any provided assets. @@ -1748,8 +1740,7 @@ O|===|* >________________>\n\ return this.clock.isRunning(); } - - private _screenShotRequests: { preserveHiDPIResolution: boolean, resolve: (image: HTMLImageElement) => void }[] = []; + private _screenShotRequests: { preserveHiDPIResolution: boolean; resolve: (image: HTMLImageElement) => void }[] = []; /** * Takes a screen shot of the current viewport and returns it as an * HTML Image Element. @@ -1757,7 +1748,7 @@ O|===|* >________________>\n\ */ public screenshot(preserveHiDPIResolution = false): Promise { const screenShotPromise = new Promise((resolve) => { - this._screenShotRequests.push({preserveHiDPIResolution, resolve}); + this._screenShotRequests.push({ preserveHiDPIResolution, resolve }); }); return screenShotPromise; } @@ -1819,4 +1810,4 @@ O|===|* >________________>\n\ } }); } -} \ No newline at end of file +} diff --git a/src/engine/EntityComponentSystem/Component.ts b/src/engine/EntityComponentSystem/Component.ts index 5b0b1df0..906ffeb3 100644 --- a/src/engine/EntityComponentSystem/Component.ts +++ b/src/engine/EntityComponentSystem/Component.ts @@ -3,7 +3,7 @@ import { Entity } from './Entity'; /** * Component Constructor Types */ -export declare type ComponentCtor = new (...args:any[]) => TComponent; +export declare type ComponentCtor = new (...args: any[]) => TComponent; /** * @@ -75,4 +75,4 @@ export abstract class Component { * Optional callback called when a component is removed from an entity */ onRemove?(previousOwner: Entity): void; -} \ No newline at end of file +} diff --git a/src/engine/EntityComponentSystem/Components/MotionComponent.ts b/src/engine/EntityComponentSystem/Components/MotionComponent.ts index 5cb5516b..6f6c1840 100644 --- a/src/engine/EntityComponentSystem/Components/MotionComponent.ts +++ b/src/engine/EntityComponentSystem/Components/MotionComponent.ts @@ -34,7 +34,6 @@ export interface Motion { } export class MotionComponent extends Component { - /** * The velocity of an entity in pixels per second */ diff --git a/src/engine/EntityComponentSystem/Components/TagsComponent.ts b/src/engine/EntityComponentSystem/Components/TagsComponent.ts index 60a1a8d2..9d23d18c 100644 --- a/src/engine/EntityComponentSystem/Components/TagsComponent.ts +++ b/src/engine/EntityComponentSystem/Components/TagsComponent.ts @@ -2,4 +2,4 @@ import { Component } from '../Component'; export class TagsComponent extends Component { public tags = new Set(); -} \ No newline at end of file +} diff --git a/src/engine/EntityComponentSystem/Components/TransformComponent.ts b/src/engine/EntityComponentSystem/Components/TransformComponent.ts index b7e5db25..a3441c48 100644 --- a/src/engine/EntityComponentSystem/Components/TransformComponent.ts +++ b/src/engine/EntityComponentSystem/Components/TransformComponent.ts @@ -6,7 +6,6 @@ import { Entity } from '../Entity'; import { Observable } from '../../Util/Observable'; import { Logger } from '../../Util/Log'; - export class TransformComponent extends Component { private _logger = Logger.getInstance(); private _parentComponent: TransformComponent | null = null; @@ -26,8 +25,8 @@ export class TransformComponent extends Component { for (const child of owner.children) { this._addChildTransform(child); } - owner.childrenAdded$.subscribe(child => this._addChildTransform(child)); - owner.childrenRemoved$.subscribe(child => { + owner.childrenAdded$.subscribe((child) => this._addChildTransform(child)); + owner.childrenRemoved$.subscribe((child) => { const childTxComponent = child.get(TransformComponent); if (childTxComponent) { childTxComponent._transform.parent = null; @@ -78,7 +77,8 @@ export class TransformComponent extends Component { this._coordPlane = value; } else { this._logger.warn( - `Cannot set coordinate plane on child entity ${this.owner?.name}, children inherit their coordinate plane from their parents.`); + `Cannot set coordinate plane on child entity ${this.owner?.name}, children inherit their coordinate plane from their parents.` + ); } } @@ -138,4 +138,4 @@ export class TransformComponent extends Component { component._z = this._z; return component; } -} \ No newline at end of file +} diff --git a/src/engine/EntityComponentSystem/Entity.ts b/src/engine/EntityComponentSystem/Entity.ts index 5b6f591f..8c7fc1c9 100644 --- a/src/engine/EntityComponentSystem/Entity.ts +++ b/src/engine/EntityComponentSystem/Entity.ts @@ -23,7 +23,7 @@ export interface EntityComponent { */ export class AddedComponent implements Message { readonly type: 'Component Added' = 'Component Added'; - constructor(public data: EntityComponent) { } + constructor(public data: EntityComponent) {} } /** @@ -38,7 +38,7 @@ export function isAddedComponent(x: Message): x is AddedCompone */ export class RemovedComponent implements Message { readonly type: 'Component Removed' = 'Component Removed'; - constructor(public data: EntityComponent) { } + constructor(public data: EntityComponent) {} } /** @@ -52,10 +52,10 @@ export function isRemovedComponent(x: Message): x is RemovedCom * Built in events supported by all entities */ export type EntityEvents = { - 'initialize': InitializeEvent; - 'preupdate': PreUpdateEvent; - 'postupdate': PostUpdateEvent; - 'kill': KillEvent + initialize: InitializeEvent; + preupdate: PreUpdateEvent; + postupdate: PostUpdateEvent; + kill: KillEvent; }; export const EntityEvents = { @@ -95,10 +95,10 @@ export class Entity implements OnIniti */ public events = new EventEmitter(); private _tags = new Set(); - public componentAdded$ = new Observable; - public componentRemoved$ = new Observable; - public tagAdded$ = new Observable; - public tagRemoved$ = new Observable; + public componentAdded$ = new Observable(); + public componentRemoved$ = new Observable(); + public tagAdded$ = new Observable(); + public tagRemoved$ = new Observable(); /** * Current components on the entity * @@ -240,7 +240,8 @@ export class Entity implements OnIniti } private _getCachedInstanceOfType( - type: ComponentCtor): MaybeKnownComponent | undefined { + type: ComponentCtor + ): MaybeKnownComponent | undefined { if (this._instanceOfComponentCacheDirty) { this._instanceOfComponentCacheDirty = false; this._instanceOfComponentCache.clear(); @@ -261,7 +262,7 @@ export class Entity implements OnIniti get(type: ComponentCtor): MaybeKnownComponent { const maybeComponent = this._getCachedInstanceOfType(type); - return maybeComponent ?? this.components.get(type) as MaybeKnownComponent; + return maybeComponent ?? (this.components.get(type) as MaybeKnownComponent); } private _parent: Entity | null = null; @@ -436,8 +437,9 @@ export class Entity implements OnIniti * @param force */ public removeComponent( - typeOrInstance: ComponentCtor | TComponent, force = false): Entity> { - + typeOrInstance: ComponentCtor | TComponent, + force = false + ): Entity> { let type: ComponentCtor; if (isComponentCtor(typeOrInstance)) { type = typeOrInstance; diff --git a/src/engine/EntityComponentSystem/EntityManager.ts b/src/engine/EntityComponentSystem/EntityManager.ts index 11b41fab..0371cc93 100644 --- a/src/engine/EntityComponentSystem/EntityManager.ts +++ b/src/engine/EntityComponentSystem/EntityManager.ts @@ -124,8 +124,8 @@ export class EntityManager { return this._entityIndex[id]; } - public getByName(name: string): Entity[]{ - return this.entities.filter(e => e.name === name); + public getByName(name: string): Entity[] { + return this.entities.filter((e) => e.name === name); } public clear(): void { diff --git a/src/engine/EntityComponentSystem/Priority.ts b/src/engine/EntityComponentSystem/Priority.ts index a940b347..18877bc4 100644 --- a/src/engine/EntityComponentSystem/Priority.ts +++ b/src/engine/EntityComponentSystem/Priority.ts @@ -7,4 +7,4 @@ export const SystemPriority = { Average: 0, Lower: 5, Lowest: Infinity -} as const; \ No newline at end of file +} as const; diff --git a/src/engine/EntityComponentSystem/Query.ts b/src/engine/EntityComponentSystem/Query.ts index e1f4a5e0..a0c4e79b 100644 --- a/src/engine/EntityComponentSystem/Query.ts +++ b/src/engine/EntityComponentSystem/Query.ts @@ -40,7 +40,11 @@ export class Query = never // TODO what happens if a user defines the same type name as a built in type // ! TODO this could be dangerous depending on the bundler's settings for names // Maybe some kind of hash function is better here? - return requiredComponents.slice().map(c => c.name).sort().join('-'); + return requiredComponents + .slice() + .map((c) => c.name) + .sort() + .join('-'); } /** @@ -74,4 +78,4 @@ export class Query = never } return this.entities; } -} \ No newline at end of file +} diff --git a/src/engine/EntityComponentSystem/QueryManager.ts b/src/engine/EntityComponentSystem/QueryManager.ts index 4f2b5c78..44f4e577 100644 --- a/src/engine/EntityComponentSystem/QueryManager.ts +++ b/src/engine/EntityComponentSystem/QueryManager.ts @@ -21,7 +21,8 @@ export class QueryManager { constructor(private _world: World) {} public createQuery>( - requiredComponents: TKnownComponentCtors[]): Query { + requiredComponents: TKnownComponentCtors[] + ): Query { const id = Query.createId(requiredComponents); if (this._queries.has(id)) { // short circuit if query is already created @@ -204,6 +205,4 @@ export class QueryManager { query.removeEntity(entity); } } - - } diff --git a/src/engine/EntityComponentSystem/System.ts b/src/engine/EntityComponentSystem/System.ts index 066f1c7d..69c4124b 100644 --- a/src/engine/EntityComponentSystem/System.ts +++ b/src/engine/EntityComponentSystem/System.ts @@ -32,7 +32,6 @@ export enum SystemType { * ``` */ export abstract class System { - /** * Determine whether the system is called in the [[SystemType.Update]] or the [[SystemType.Draw]] phase. Update is first, then Draw. */ diff --git a/src/engine/EntityComponentSystem/TagQuery.ts b/src/engine/EntityComponentSystem/TagQuery.ts index bd9cedc3..ced97cad 100644 --- a/src/engine/EntityComponentSystem/TagQuery.ts +++ b/src/engine/EntityComponentSystem/TagQuery.ts @@ -1,7 +1,6 @@ import { Observable } from '../Util/Observable'; import { Entity } from './Entity'; - export class TagQuery { public readonly id: string; public tags = new Set(); @@ -57,4 +56,4 @@ export class TagQuery { } return this.entities; } -} \ No newline at end of file +} diff --git a/src/engine/EntityComponentSystem/Types.ts b/src/engine/EntityComponentSystem/Types.ts index 6e6da39c..d48482d1 100644 --- a/src/engine/EntityComponentSystem/Types.ts +++ b/src/engine/EntityComponentSystem/Types.ts @@ -1 +1 @@ -export type MaybeKnownComponent = Component extends TKnownComponents ? Component : (Component | undefined); \ No newline at end of file +export type MaybeKnownComponent = Component extends TKnownComponents ? Component : Component | undefined; diff --git a/src/engine/EntityComponentSystem/World.ts b/src/engine/EntityComponentSystem/World.ts index 66e86fa2..8bc6fc74 100644 --- a/src/engine/EntityComponentSystem/World.ts +++ b/src/engine/EntityComponentSystem/World.ts @@ -26,8 +26,7 @@ export class World { * Query the ECS world for entities that match your components * @param requiredTypes */ - query>( - requiredTypes: TKnownComponentCtors[]): Query { + query>(requiredTypes: TKnownComponentCtors[]): Query { return this.queryManager.createQuery(requiredTypes); } diff --git a/src/engine/EntityComponentSystem/tsconfig.json b/src/engine/EntityComponentSystem/tsconfig.json index b2e9e0b8..20d5e2e0 100644 --- a/src/engine/EntityComponentSystem/tsconfig.json +++ b/src/engine/EntityComponentSystem/tsconfig.json @@ -3,4 +3,4 @@ "compilerOptions": { "strict": true } -} \ No newline at end of file +} diff --git a/src/engine/EventDispatcher.ts b/src/engine/EventDispatcher.ts index f13693b8..118b3f8d 100644 --- a/src/engine/EventDispatcher.ts +++ b/src/engine/EventDispatcher.ts @@ -16,7 +16,7 @@ export class EventDispatcher implements Eventable { this._wiredEventDispatchers = []; } - private _deferedHandlerRemovals: {name: string, handler?: (...args: any[]) => any }[] = []; + private _deferedHandlerRemovals: { name: string; handler?: (...args: any[]) => any }[] = []; private _processDeferredHandlerRemovals() { for (const eventHandler of this._deferedHandlerRemovals) { this._removeHandler(eventHandler.name, eventHandler.handler); @@ -80,7 +80,7 @@ export class EventDispatcher implements Eventable { * @param handler Optionally the specific handler to unsubscribe */ public off(eventName: string, handler?: (event: GameEvent) => void) { - this._deferedHandlerRemovals.push({name: eventName, handler}); + this._deferedHandlerRemovals.push({ name: eventName, handler }); } private _removeHandler(eventName: string, handler?: (event: GameEvent) => void) { diff --git a/src/engine/EventEmitter.ts b/src/engine/EventEmitter.ts index 144bd7e9..ddbba0cb 100644 --- a/src/engine/EventEmitter.ts +++ b/src/engine/EventEmitter.ts @@ -49,10 +49,10 @@ export class EventEmitter { off(eventName: string): void; off | string>(eventName: TEventName, handler?: Handler): void { if (handler) { - const newListeners = this._listeners[eventName]?.filter(h => h !== handler); + const newListeners = this._listeners[eventName]?.filter((h) => h !== handler); this._listeners[eventName] = newListeners; - const newOnceListeners = this._listenersOnce[eventName]?.filter(h => h !== handler); + const newOnceListeners = this._listenersOnce[eventName]?.filter((h) => h !== handler); this._listenersOnce[eventName] = newOnceListeners; } else { delete this._listeners[eventName]; @@ -105,4 +105,4 @@ export class EventEmitter { unpause(): void { this._paused = false; } -} \ No newline at end of file +} diff --git a/src/engine/Events.ts b/src/engine/Events.ts index 73e27b4b..97bf1ad5 100644 --- a/src/engine/Events.ts +++ b/src/engine/Events.ts @@ -247,7 +247,11 @@ export class GameStopEvent extends GameEvent { * */ export class PreDrawEvent extends GameEvent { - constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) { + constructor( + public ctx: ExcaliburGraphicsContext, + public delta: number, + public target: Entity | Scene | Engine | TileMap + ) { super(); } } @@ -258,7 +262,11 @@ export class PreDrawEvent extends GameEvent { * */ export class PostDrawEvent extends GameEvent { - constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) { + constructor( + public ctx: ExcaliburGraphicsContext, + public delta: number, + public target: Entity | Scene | Engine | TileMap + ) { super(); } } @@ -270,7 +278,11 @@ export class PostDrawEvent extends GameEvent * */ export class PreTransformDrawEvent extends GameEvent { - constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) { + constructor( + public ctx: ExcaliburGraphicsContext, + public delta: number, + public target: Entity + ) { super(); } } @@ -281,7 +293,11 @@ export class PreTransformDrawEvent extends GameEvent { * */ export class PostTransformDrawEvent extends GameEvent { - constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) { + constructor( + public ctx: ExcaliburGraphicsContext, + public delta: number, + public target: Entity + ) { super(); } } @@ -290,7 +306,10 @@ export class PostTransformDrawEvent extends GameEvent { * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts. */ export class PreDebugDrawEvent extends GameEvent { - constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) { + constructor( + public ctx: ExcaliburGraphicsContext, + public target: Entity | Actor | Scene | Engine + ) { super(); } } @@ -299,7 +318,10 @@ export class PreDebugDrawEvent extends GameEvent { - constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) { + constructor( + public ctx: ExcaliburGraphicsContext, + public target: Entity | Actor | Scene | Engine + ) { super(); } } @@ -308,7 +330,11 @@ export class PostDebugDrawEvent extends GameEvent extends GameEvent { - constructor(public engine: Engine, public delta: number, public target: T) { + constructor( + public engine: Engine, + public delta: number, + public target: T + ) { super(); } } @@ -317,7 +343,11 @@ export class PreUpdateEvent extends GameEvent * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends. */ export class PostUpdateEvent extends GameEvent { - constructor(public engine: Engine, public delta: number, public target: T) { + constructor( + public engine: Engine, + public delta: number, + public target: T + ) { super(); } } @@ -326,7 +356,10 @@ export class PostUpdateEvent extends GameEvent< * The 'preframe' event is emitted on the engine, before the frame begins. */ export class PreFrameEvent extends GameEvent { - constructor(public engine: Engine, public prevStats: FrameStats) { + constructor( + public engine: Engine, + public prevStats: FrameStats + ) { super(); this.target = engine; } @@ -336,7 +369,10 @@ export class PreFrameEvent extends GameEvent { * The 'postframe' event is emitted on the engine, after a frame ends. */ export class PostFrameEvent extends GameEvent { - constructor(public engine: Engine, public stats: FrameStats) { + constructor( + public engine: Engine, + public stats: FrameStats + ) { super(); this.target = engine; } @@ -346,7 +382,10 @@ export class PostFrameEvent extends GameEvent { * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event. */ export class GamepadConnectEvent extends GameEvent { - constructor(public index: number, public gamepad: Gamepad) { + constructor( + public index: number, + public gamepad: Gamepad + ) { super(); this.target = gamepad; } @@ -356,7 +395,10 @@ export class GamepadConnectEvent extends GameEvent { * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event. */ export class GamepadDisconnectEvent extends GameEvent { - constructor(public index: number, public gamepad: Gamepad) { + constructor( + public index: number, + public gamepad: Gamepad + ) { super(); this.target = gamepad; } @@ -370,7 +412,11 @@ export class GamepadButtonEvent extends GameEvent { * @param button The Gamepad button * @param value A numeric value between 0 and 1 */ - constructor(public button: Buttons, public value: number, public target: Gamepad) { + constructor( + public button: Buttons, + public value: number, + public target: Gamepad + ) { super(); } } @@ -383,7 +429,11 @@ export class GamepadAxisEvent extends GameEvent { * @param axis The Gamepad axis * @param value A numeric value between -1 and 1 */ - constructor(public axis: Axes, public value: number, public target: Gamepad) { + constructor( + public axis: Axes, + public value: number, + public target: Gamepad + ) { super(); } } @@ -416,7 +466,13 @@ export class PreCollisionEvent extends Gam * @param side The side that did collide with the current actor * @param intersection Intersection vector */ - constructor(actor: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) { + constructor( + actor: T, + public other: T, + public side: Side, + public intersection: Vector, + public contact: CollisionContact + ) { super(); this.target = actor; } @@ -447,19 +509,41 @@ export class PostCollisionEvent extends Gam } export class ContactStartEvent { - constructor(public target: T, public other: T, public side: Side, public contact: CollisionContact) {} + constructor( + public target: T, + public other: T, + public side: Side, + public contact: CollisionContact + ) {} } export class ContactEndEvent { - constructor(public target: T, public other: T, public side: Side, public lastContact: CollisionContact) {} + constructor( + public target: T, + public other: T, + public side: Side, + public lastContact: CollisionContact + ) {} } export class CollisionPreSolveEvent { - constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {} + constructor( + public target: T, + public other: T, + public side: Side, + public intersection: Vector, + public contact: CollisionContact + ) {} } export class CollisionPostSolveEvent { - constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {} + constructor( + public target: T, + public other: T, + public side: Side, + public intersection: Vector, + public contact: CollisionContact + ) {} } /** @@ -473,7 +557,12 @@ export class CollisionStartEvent extends GameEvent< /** * @param engine The reference to the current engine */ - constructor(public engine: Engine, public target: T) { + constructor( + public engine: Engine, + public target: T + ) { super(); } } @@ -527,7 +624,10 @@ export class ActivateEvent extends GameEvent { /** * @param context The context for the scene activation */ - constructor(public context: SceneActivationContext, public target: Scene) { + constructor( + public context: SceneActivationContext, + public target: Scene + ) { super(); } } @@ -539,7 +639,10 @@ export class DeactivateEvent extends GameEvent { /** * @param context The context for the scene deactivation */ - constructor(public context: SceneActivationContext, public target: Scene) { + constructor( + public context: SceneActivationContext, + public target: Scene + ) { super(); } } @@ -563,13 +666,19 @@ export class EnterViewPortEvent extends GameEvent { } export class EnterTriggerEvent extends GameEvent { - constructor(public target: Trigger, public actor: Actor) { + constructor( + public target: Trigger, + public actor: Actor + ) { super(); } } export class ExitTriggerEvent extends GameEvent { - constructor(public target: Trigger, public actor: Actor) { + constructor( + public target: Trigger, + public actor: Actor + ) { super(); } } @@ -578,7 +687,10 @@ export class ExitTriggerEvent extends GameEvent { * Event thrown on an [[Actor]] when an action starts. */ export class ActionStartEvent extends GameEvent { - constructor(public action: Action, public target: Entity) { + constructor( + public action: Action, + public target: Entity + ) { super(); } } @@ -587,7 +699,10 @@ export class ActionStartEvent extends GameEvent { * Event thrown on an [[Actor]] when an action completes. */ export class ActionCompleteEvent extends GameEvent { - constructor(public action: Action, public target: Entity) { + constructor( + public action: Action, + public target: Entity + ) { super(); } } diff --git a/src/engine/Events/ExEvent.ts b/src/engine/Events/ExEvent.ts index 59d521da..93e1562e 100644 --- a/src/engine/Events/ExEvent.ts +++ b/src/engine/Events/ExEvent.ts @@ -1,4 +1,3 @@ - export abstract class ExEvent { abstract readonly type: TName; @@ -9,4 +8,4 @@ export abstract class ExEvent { public cancel() { this._active = false; } -} \ No newline at end of file +} diff --git a/src/engine/Events/MediaEvents.ts b/src/engine/Events/MediaEvents.ts index c87b2c87..40e9c796 100644 --- a/src/engine/Events/MediaEvents.ts +++ b/src/engine/Events/MediaEvents.ts @@ -29,7 +29,10 @@ export class MediaEvent extends GameEvent { // stubbed } - constructor(public target: Sound, protected _name: string = 'MediaEvent') { + constructor( + public target: Sound, + protected _name: string = 'MediaEvent' + ) { super(); } @@ -66,7 +69,10 @@ export class MediaEvent extends GameEvent { } export class NativeSoundEvent extends MediaEvent { - constructor(target: Sound, public track?: WebAudioInstance) { + constructor( + target: Sound, + public track?: WebAudioInstance + ) { super(target, 'NativeSoundEvent'); } } @@ -74,7 +80,10 @@ export class NativeSoundEvent extends MediaEvent { export class NativeSoundProcessedEvent extends MediaEvent { public data: string | AudioBuffer; - constructor(target: Sound, private _processedData: string | AudioBuffer) { + constructor( + target: Sound, + private _processedData: string | AudioBuffer + ) { super(target, 'NativeSoundProcessedEvent'); this.data = this._processedData; diff --git a/src/engine/Events/PointerEvents.ts b/src/engine/Events/PointerEvents.ts index 3b61eb7c..025aaa62 100644 --- a/src/engine/Events/PointerEvents.ts +++ b/src/engine/Events/PointerEvents.ts @@ -2,12 +2,12 @@ import { GlobalCoordinates } from '../Math/global-coordinates'; import { WheelDeltaMode } from '../Input/WheelDeltaMode'; import { ExEvent } from './ExEvent'; - export abstract class PointerEvent extends ExEvent<'down' | 'up' | 'move' | 'cancel'> { constructor( public pointerId: number, public coordinates: GlobalCoordinates, - public nativeEvent: Event) { + public nativeEvent: Event + ) { super(); } } @@ -42,4 +42,4 @@ export class Wheel extends ExEvent<'wheel'> { ) { super(); } -} \ No newline at end of file +} diff --git a/src/engine/Flags.ts b/src/engine/Flags.ts index b65da081..2b3a7d46 100644 --- a/src/engine/Flags.ts +++ b/src/engine/Flags.ts @@ -1,4 +1,3 @@ - /** * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction** * after which they are frozen and are read-only. @@ -9,7 +8,6 @@ export class Flags { private static _FROZEN = false; private static _FLAGS: Record = {}; - /** * Force excalibur to load the Canvas 2D graphics context fallback * @warning not all features of excalibur are supported in the Canvas 2D fallback diff --git a/src/engine/Graphics/Animation.ts b/src/engine/Graphics/Animation.ts index 0c4a60b8..b85b2f02 100644 --- a/src/engine/Graphics/Animation.ts +++ b/src/engine/Graphics/Animation.ts @@ -118,7 +118,7 @@ export interface FromSpriteSheetOptions { * You may optionally specify a duration for the frame in milliseconds as well, this will override * the default duration. */ - frameCoordinates: {x: number, y: number, duration?: number, options?: GetSpriteOptions}[]; + frameCoordinates: { x: number; y: number; duration?: number; options?: GetSpriteOptions }[]; /** * Optionally specify a default duration for frames in milliseconds */ @@ -132,7 +132,7 @@ export interface FromSpriteSheetOptions { /** * Optionally specify the animation strategy for this animation, by default animations loop [[AnimationStrategy.Loop]] */ - strategy?: AnimationStrategy + strategy?: AnimationStrategy; /** * Optionally specify the animation should be reversed */ @@ -200,7 +200,6 @@ export class Animation extends Graphic implements HasTick { return 0; } - /** * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame * and optional [[AnimationStrategy]] @@ -266,7 +265,7 @@ export class Animation extends Graphic implements HasTick { const defaultDuration = durationPerFrameMs ?? 100; const frames: Frame[] = []; for (const coord of frameCoordinates) { - const {x, y, duration, options } = coord; + const { x, y, duration, options } = coord; const sprite = spriteSheet.getSprite(x, y, options); if (sprite) { frames.push({ @@ -360,7 +359,7 @@ export class Animation extends Graphic implements HasTick { public get direction(): AnimationDirection { // Keep logically consistent with ping-pong direction // If ping-pong is forward = 1 and reversed is true then we are logically reversed - const reversed = (this._reversed && this._pingPongDirection === 1) ? true : false; + const reversed = this._reversed && this._pingPongDirection === 1 ? true : false; return reversed ? AnimationDirection.Backward : AnimationDirection.Forward; } @@ -389,7 +388,7 @@ export class Animation extends Graphic implements HasTick { this._timeLeftInFrame = this.frameDuration; const maybeFrame = this.frames[this._currentFrame]; if (maybeFrame) { - this._timeLeftInFrame = (maybeFrame?.duration || this.frameDuration); + this._timeLeftInFrame = maybeFrame?.duration || this.frameDuration; } } @@ -432,7 +431,7 @@ export class Animation extends Graphic implements HasTick { const maybeFrame = this.frames[this._currentFrame]; if (maybeFrame && !this._done) { this._timeLeftInFrame = duration ?? (maybeFrame?.duration || this.frameDuration); - this.events.emit('frame', {...maybeFrame, frameIndex: this.currentFrameIndex }); + this.events.emit('frame', { ...maybeFrame, frameIndex: this.currentFrameIndex }); } } @@ -503,7 +502,7 @@ export class Animation extends Graphic implements HasTick { // if it's the first frame emit frame event if (this._firstTick) { this._firstTick = false; - this.events.emit('frame', {...this.currentFrame, frameIndex: this.currentFrameIndex }); + this.events.emit('frame', { ...this.currentFrame, frameIndex: this.currentFrameIndex }); } this._timeLeftInFrame -= elapsedMilliseconds * this._speed; diff --git a/src/engine/Graphics/Circle.ts b/src/engine/Graphics/Circle.ts index d920d81a..314fe991 100644 --- a/src/engine/Graphics/Circle.ts +++ b/src/engine/Graphics/Circle.ts @@ -24,7 +24,7 @@ export class Circle extends Raster { constructor(options: RasterOptions & CircleOptions) { super(options); const lineWidth = options.lineWidth ?? (options.strokeColor ? 1 : 0); // default lineWidth in canvas is 1px - this.padding = options.padding ?? 2 + (lineWidth / 2); // default 2 padding for circles looks nice + this.padding = options.padding ?? 2 + lineWidth / 2; // default 2 padding for circles looks nice this.radius = options.radius; this.filtering = options.filtering ?? ImageFiltering.Blended; this.rasterize(); diff --git a/src/engine/Graphics/Context/ExcaliburGraphicsContext.ts b/src/engine/Graphics/Context/ExcaliburGraphicsContext.ts index 3956d73a..d8a6083c 100644 --- a/src/engine/Graphics/Context/ExcaliburGraphicsContext.ts +++ b/src/engine/Graphics/Context/ExcaliburGraphicsContext.ts @@ -30,14 +30,16 @@ export interface AntialiasOptions { * * Default true, with max samples that the platform supports */ - multiSampleAntialiasing?: boolean | { - /** - * Optionally specify number of samples (will be clamped to the max the platform supports) - * - * Default most platforms are 16 samples - */ - samples: number; - }; + multiSampleAntialiasing?: + | boolean + | { + /** + * Optionally specify number of samples (will be clamped to the max the platform supports) + * + * Default most platforms are 16 samples + */ + samples: number; + }; /** * Sets the default image filtering for excalibur * @@ -92,13 +94,15 @@ export interface ExcaliburGraphicsContextOptions { * * By default enabled */ - multiSampleAntialiasing?: boolean | { - /** - * Specify number of samples to use during the multi sample anti-alias, if not specified the max will be used. - * Limited by the hardware (usually 16) - */ - samples: number - }, + multiSampleAntialiasing?: + | boolean + | { + /** + * Specify number of samples to use during the multi sample anti-alias, if not specified the max will be used. + * Limited by the hardware (usually 16) + */ + samples: number; + }; /** * UV padding in pixels to use in the internal image rendering * diff --git a/src/engine/Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts b/src/engine/Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts index b550a414..6771d8ad 100644 --- a/src/engine/Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts +++ b/src/engine/Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts @@ -139,9 +139,11 @@ export class ExcaliburGraphicsContext2DCanvas implements ExcaliburGraphicsContex constructor(options: ExcaliburGraphicsContext2DOptions) { const { canvasElement, context, enableTransparency, snapToPixel, antialiasing: smoothing, backgroundColor } = options; - this.__ctx = context ?? canvasElement.getContext('2d', { - alpha: enableTransparency ?? true - }); + this.__ctx = + context ?? + canvasElement.getContext('2d', { + alpha: enableTransparency ?? true + }); if (!this.__ctx) { throw new Error('Cannot build new ExcaliburGraphicsContext2D for some reason!'); } @@ -217,13 +219,10 @@ export class ExcaliburGraphicsContext2DCanvas implements ExcaliburGraphicsContex this.__ctx.beginPath(); this.__ctx.strokeStyle = color.toString(); this.__ctx.moveTo( - this.snapToPixel ? ~~ (start.x + pixelSnapEpsilon) : start.x, + this.snapToPixel ? ~~(start.x + pixelSnapEpsilon) : start.x, this.snapToPixel ? ~~(start.y + pixelSnapEpsilon) : start.y ); - this.__ctx.lineTo( - this.snapToPixel ? ~~ (end.x + pixelSnapEpsilon) : end.x, - this.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y - ); + this.__ctx.lineTo(this.snapToPixel ? ~~(end.x + pixelSnapEpsilon) : end.x, this.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y); this.__ctx.lineWidth = thickness; this.__ctx.stroke(); this.__ctx.closePath(); @@ -254,7 +253,10 @@ export class ExcaliburGraphicsContext2DCanvas implements ExcaliburGraphicsContex this.__ctx.fillStyle = color.toString(); this.__ctx.arc( this.snapToPixel ? ~~(pos.x + pixelSnapEpsilon) : pos.x, - this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2 + this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y, + radius, + 0, + Math.PI * 2 ); this.__ctx.fill(); if (stroke) { diff --git a/src/engine/Graphics/Context/ExcaliburGraphicsContextWebGL.ts b/src/engine/Graphics/Context/ExcaliburGraphicsContextWebGL.ts index e0fd6827..1c1ed574 100644 --- a/src/engine/Graphics/Context/ExcaliburGraphicsContextWebGL.ts +++ b/src/engine/Graphics/Context/ExcaliburGraphicsContextWebGL.ts @@ -87,9 +87,9 @@ export interface WebGLGraphicsContextInfo { } export interface ExcaliburGraphicsContextWebGLOptions extends ExcaliburGraphicsContextOptions { - context?: WebGL2RenderingContext, - handleContextLost?: (e: Event) => void, - handleContextRestored?: (e: Event) => void + context?: WebGL2RenderingContext; + handleContextLost?: (e: Event) => void; + handleContextRestored?: (e: Event) => void; } export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { @@ -106,10 +106,12 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { instance.renderer = undefined; instance.args = undefined; return instance; - }, 4000); + }, + 4000 + ); private _drawCallIndex = 0; - private _drawCalls: DrawCall[] = (new Array(4000)).fill(null); + private _drawCalls: DrawCall[] = new Array(4000).fill(null); // Main render target private _renderTarget: RenderTarget; @@ -143,7 +145,6 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { */ public readonly smoothing: boolean = false; - /** * Whether the pixel art sampler is enabled for smooth sub pixel anti-aliasing */ @@ -153,7 +154,7 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { * UV padding in pixels to use in internal image rendering to prevent texture bleed * */ - public uvPadding = .01; + public uvPadding = 0.01; public backgroundColor: Color = Color.ExcaliburBlue; @@ -231,13 +232,15 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { handleContextLost, handleContextRestored } = options; - this.__gl = context ?? canvasElement.getContext('webgl2', { - antialias: antialiasing ?? this.smoothing, - premultipliedAlpha: false, - alpha: enableTransparency ?? this.transparency, - depth: false, - powerPreference: powerPreference ?? 'high-performance' - }); + this.__gl = + context ?? + canvasElement.getContext('webgl2', { + antialias: antialiasing ?? this.smoothing, + premultipliedAlpha: false, + alpha: enableTransparency ?? this.transparency, + depth: false, + powerPreference: powerPreference ?? 'high-performance' + }); if (!this.__gl) { throw Error('Failed to retrieve webgl context from browser'); } @@ -307,17 +310,18 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // Setup builtin renderers - this.register(new ImageRenderer({ - uvPadding: this.uvPadding, - pixelArtSampler: this.pixelArtSampler - })); + this.register( + new ImageRenderer({ + uvPadding: this.uvPadding, + pixelArtSampler: this.pixelArtSampler + }) + ); this.register(new MaterialRenderer()); this.register(new RectangleRenderer()); this.register(new CircleRenderer()); this.register(new PointRenderer()); this.register(new LineRenderer()); - this.materialScreenTexture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, this.materialScreenTexture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); @@ -391,7 +395,8 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { if (!this._isDrawLifecycle) { this._logger.warnOnce( `Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\n` + - `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`); + `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.` + ); } if (this._isContextLost) { this._logger.errorOnce(`Unable to draw ${rendererName}, the webgl context is lost`); @@ -588,13 +593,13 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { const uniforms = shader.getUniforms(); this._totalPostProcessorTime += delta; - if (uniforms.find(u => u.name ==='u_time_ms')) { + if (uniforms.find((u) => u.name === 'u_time_ms')) { shader.setUniformFloat('u_time_ms', this._totalPostProcessorTime); } - if (uniforms.find(u => u.name ==='u_elapsed_ms')) { + if (uniforms.find((u) => u.name === 'u_elapsed_ms')) { shader.setUniformFloat('u_elapsed_ms', delta); } - if (uniforms.find(u => u.name ==='u_resolution')) { + if (uniforms.find((u) => u.name === 'u_resolution')) { shader.setUniformFloatVector('u_resolution', vec(this.width, this.height)); } @@ -618,7 +623,7 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { * @returns Material */ public createMaterial(options: Omit): Material { - const material = new Material({...options, graphicsContext: this}); + const material = new Material({ ...options, graphicsContext: this }); return material; } @@ -682,8 +687,10 @@ export class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext { const zIndex = a.z - b.z; const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer); const priority = a.priority - b.priority; - if (zIndex === 0) { // sort by z first - if (priority === 0) { // sort by priority + if (zIndex === 0) { + // sort by z first + if (priority === 0) { + // sort by priority return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order } return priority; diff --git a/src/engine/Graphics/Context/circle-renderer/circle-renderer.ts b/src/engine/Graphics/Context/circle-renderer/circle-renderer.ts index e34463c0..ea287b70 100644 --- a/src/engine/Graphics/Context/circle-renderer/circle-renderer.ts +++ b/src/engine/Graphics/Context/circle-renderer/circle-renderer.ts @@ -216,5 +216,4 @@ export class CircleRenderer implements RendererPlugin { this._circleCount = 0; this._vertexIndex = 0; } - -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/draw-call.ts b/src/engine/Graphics/Context/draw-call.ts index 73314a8f..4a95e0d2 100644 --- a/src/engine/Graphics/Context/draw-call.ts +++ b/src/engine/Graphics/Context/draw-call.ts @@ -14,4 +14,4 @@ export class DrawCall { material: null }; public args: any[]; -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/image-renderer/image-renderer.ts b/src/engine/Graphics/Context/image-renderer/image-renderer.ts index 68d07745..31e42e52 100644 --- a/src/engine/Graphics/Context/image-renderer/image-renderer.ts +++ b/src/engine/Graphics/Context/image-renderer/image-renderer.ts @@ -138,7 +138,8 @@ export class ImageRenderer implements RendererPlugin { filtering, wrapping: { x: wrapX, y: wrapY } }, - force); + force + ); // remove force attribute after upload image.removeAttribute('forceUpload'); if (this._textures.indexOf(texture) === -1) { @@ -194,11 +195,11 @@ export class ImageRenderer implements RendererPlugin { return maybeHeight; } - private _view = [0, 0, 0, 0]; private _dest = [0, 0]; private _quad = [0, 0, 0, 0, 0, 0, 0, 0]; - draw(image: HTMLImageSource, + draw( + image: HTMLImageSource, sx: number, sy: number, swidth?: number, @@ -206,8 +207,8 @@ export class ImageRenderer implements RendererPlugin { dx?: number, dy?: number, dwidth?: number, - dheight?: number): void { - + dheight?: number + ): void { // Force a render if the batch is full if (this._isFull()) { this.flush(); @@ -398,4 +399,4 @@ export class ImageRenderer implements RendererPlugin { this._imageToWidth.clear(); this._imageToHeight.clear(); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/line-renderer/line-renderer.ts b/src/engine/Graphics/Context/line-renderer/line-renderer.ts index 5efd878c..bc1b9272 100644 --- a/src/engine/Graphics/Context/line-renderer/line-renderer.ts +++ b/src/engine/Graphics/Context/line-renderer/line-renderer.ts @@ -72,7 +72,6 @@ export class LineRenderer implements RendererPlugin { const finalStart = transform.multiply(start); const finalEnd = transform.multiply(end); - const vertexBuffer = this._vertexBuffer.bufferData; // Start vertexBuffer[this._vertexIndex++] = finalStart.x; diff --git a/src/engine/Graphics/Context/material-renderer/material-renderer.ts b/src/engine/Graphics/Context/material-renderer/material-renderer.ts index 627e1b34..45dcfaaa 100644 --- a/src/engine/Graphics/Context/material-renderer/material-renderer.ts +++ b/src/engine/Graphics/Context/material-renderer/material-renderer.ts @@ -10,7 +10,6 @@ import { RendererPlugin } from '../renderer'; import { VertexBuffer } from '../vertex-buffer'; import { VertexLayout } from '../vertex-layout'; - export class MaterialRenderer implements RendererPlugin { public readonly type: string = 'ex.material'; public priority: number = 0; @@ -56,7 +55,8 @@ export class MaterialRenderer implements RendererPlugin { this._gl = null; } - draw(image: HTMLImageSource, + draw( + image: HTMLImageSource, sx: number, sy: number, swidth?: number, @@ -64,7 +64,8 @@ export class MaterialRenderer implements RendererPlugin { dx?: number, dy?: number, dwidth?: number, - dheight?: number): void { + dheight?: number + ): void { const gl = this._gl; // Extract context info @@ -107,8 +108,8 @@ export class MaterialRenderer implements RendererPlugin { const imageWidth = image.width || width; const imageHeight = image.height || height; - const uvx0 = (sx) / imageWidth; - const uvy0 = (sy) / imageHeight; + const uvx0 = sx / imageWidth; + const uvy0 = sy / imageHeight; const uvx1 = (sx + sw - 0.01) / imageWidth; const uvy1 = (sy + sh - 0.01) / imageHeight; @@ -218,7 +219,8 @@ export class MaterialRenderer implements RendererPlugin { filtering, wrapping: { x: wrapX, y: wrapY } }, - force); + force + ); // remove force attribute after upload image.removeAttribute('forceUpload'); if (this._textures.indexOf(texture) === -1) { @@ -234,4 +236,4 @@ export class MaterialRenderer implements RendererPlugin { flush(): void { // flush does not do anything, material renderer renders immediately per draw } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/material.ts b/src/engine/Graphics/Context/material.ts index 2d1bf836..23f5ce90 100644 --- a/src/engine/Graphics/Context/material.ts +++ b/src/engine/Graphics/Context/material.ts @@ -41,7 +41,7 @@ export interface MaterialOptions { * } * ``` */ - vertexSource?: string, + vertexSource?: string; /** * Add custom fragment shader @@ -62,19 +62,19 @@ export interface MaterialOptions { * * `uniform float u_opacity` - The current opacity of the graphics context * */ - fragmentSource: string, + fragmentSource: string; /** * Add custom color, by default ex.Color.Transparent */ - color?: Color, + color?: Color; /** * Add additional images to the material, you are limited by the GPU's maximum texture slots * * Specify a dictionary of uniform sampler names to ImageSource */ - images?: Record + images?: Record; } const defaultVertexSource = `#version 300 es @@ -100,8 +100,7 @@ void main() { `; export interface MaterialImageOptions { - filtering?: ImageFiltering, - + filtering?: ImageFiltering; } export class Material { @@ -179,8 +178,10 @@ export class Material { if (this._images.size < this._maxTextureSlots) { this._images.set(textureUniformName, image); } else { - this._logger.warn(`Max number texture slots ${this._maxTextureSlots} have been reached for material "${this.name}", `+ - `no more textures will be uploaded due to hardware constraints.`); + this._logger.warn( + `Max number texture slots ${this._maxTextureSlots} have been reached for material "${this.name}", ` + + `no more textures will be uploaded due to hardware constraints.` + ); } } @@ -204,7 +205,8 @@ export class Material { filtering, wrapping: { x: wrapX, y: wrapY } }, - force); + force + ); // remove force attribute after upload imageElement.removeAttribute('forceUpload'); if (!this._textures.has(image)) { @@ -215,12 +217,13 @@ export class Material { } uploadAndBind(gl: WebGL2RenderingContext, startingTextureSlot: number = 2) { - let textureSlot = startingTextureSlot; for (const [textureName, image] of this._images.entries()) { if (!image.isLoaded()) { - this._logger.warnOnce(`Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` + - ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/`); + this._logger.warnOnce( + `Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` + + ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/` + ); continue; } // skip unloaded images, maybe warn const texture = this._loadImageSource(image); @@ -239,9 +242,8 @@ export class Material { this._shader.use(); // Apply standard uniforms this._shader.trySetUniformFloatColor('u_color', this._color); - } else { throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`); } } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/quad-index-buffer.ts b/src/engine/Graphics/Context/quad-index-buffer.ts index 8971b9e5..07a0d279 100644 --- a/src/engine/Graphics/Context/quad-index-buffer.ts +++ b/src/engine/Graphics/Context/quad-index-buffer.ts @@ -46,11 +46,11 @@ export class QuadIndexBuffer { // TODO Should we error if this happens?? maybe not might crash mid game if (numberOfQuads > maxUint16Index) { this._logger.warn( - `Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`); + `Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})` + ); } } - let currentQuad = 0; for (let i = 0; i < totalVertices; i += 6) { // first triangle @@ -92,4 +92,4 @@ export class QuadIndexBuffer { gl.deleteBuffer(this.buffer); this._gl = null; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/rectangle-renderer/rectangle-renderer.ts b/src/engine/Graphics/Context/rectangle-renderer/rectangle-renderer.ts index c1008a00..09494acd 100644 --- a/src/engine/Graphics/Context/rectangle-renderer/rectangle-renderer.ts +++ b/src/engine/Graphics/Context/rectangle-renderer/rectangle-renderer.ts @@ -26,7 +26,6 @@ export class RectangleRenderer implements RendererPlugin { private _rectangleCount: number = 0; private _vertexIndex: number = 0; - initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void { this._gl = gl; this._context = context; @@ -89,7 +88,6 @@ export class RectangleRenderer implements RendererPlugin { } drawLine(start: Vector, end: Vector, color: Color, thickness: number = 1) { - if (this._isFull()) { this.flush(); } @@ -223,7 +221,8 @@ export class RectangleRenderer implements RendererPlugin { height: number, color: Color, stroke: Color = Color.Transparent, - strokeThickness: number = 0): void { + strokeThickness: number = 0 + ): void { if (this._isFull()) { this.flush(); } @@ -333,7 +332,6 @@ export class RectangleRenderer implements RendererPlugin { vertexBuffer[this._vertexIndex++] = stroke.b / 255; vertexBuffer[this._vertexIndex++] = stroke.a; vertexBuffer[this._vertexIndex++] = strokeThickness; - } hasPendingDraws(): boolean { @@ -369,5 +367,4 @@ export class RectangleRenderer implements RendererPlugin { this._rectangleCount = 0; this._vertexIndex = 0; } - -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/render-source.ts b/src/engine/Graphics/Context/render-source.ts index 18216839..8bb382ff 100644 --- a/src/engine/Graphics/Context/render-source.ts +++ b/src/engine/Graphics/Context/render-source.ts @@ -1,7 +1,8 @@ export class RenderSource { constructor( private _gl: WebGLRenderingContext, - private _texture: WebGLTexture) {} + private _texture: WebGLTexture + ) {} public use() { const gl = this._gl; @@ -13,4 +14,4 @@ export class RenderSource { const gl = this._gl; gl.bindTexture(gl.TEXTURE_2D, null); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/render-target.ts b/src/engine/Graphics/Context/render-target.ts index 0c2d1463..7144a5f3 100644 --- a/src/engine/Graphics/Context/render-target.ts +++ b/src/engine/Graphics/Context/render-target.ts @@ -9,7 +9,6 @@ declare global { } } - export interface RenderTargetOptions { gl: WebGL2RenderingContext; width: number; @@ -80,7 +79,8 @@ export class RenderTarget { Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, - this.height); + this.height + ); } } @@ -114,7 +114,8 @@ export class RenderTarget { Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, - this.height); + this.height + ); gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer); } @@ -133,7 +134,6 @@ export class RenderTarget { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - // attach the texture as the first color attachment const attachmentPoint = gl.COLOR_ATTACHMENT0; @@ -161,18 +161,12 @@ export class RenderTarget { gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]); - gl.blitFramebuffer( - 0, 0, this.width, this.height, - 0, 0, this.width, this.height, - gl.COLOR_BUFFER_BIT, gl.LINEAR); + gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR); } else { gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.frameBuffer); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]); - gl.blitFramebuffer( - 0, 0, this.width, this.height, - 0, 0, this.width, this.height, - gl.COLOR_BUFFER_BIT, gl.LINEAR); + gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR); } } @@ -182,10 +176,7 @@ export class RenderTarget { gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.frameBuffer); gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]); - gl.blitFramebuffer( - 0, 0, this.width, this.height, - 0, 0, this.width, this.height, - gl.COLOR_BUFFER_BIT, gl.LINEAR); + gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR); } } @@ -223,4 +214,4 @@ export class RenderTarget { gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.bindTexture(gl.TEXTURE_2D, null); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/renderer.ts b/src/engine/Graphics/Context/renderer.ts index 861ea45c..deb0276a 100644 --- a/src/engine/Graphics/Context/renderer.ts +++ b/src/engine/Graphics/Context/renderer.ts @@ -1,6 +1,5 @@ import { ExcaliburGraphicsContextWebGL } from './ExcaliburGraphicsContextWebGL'; - /** * Interface that defines an Excalibur Renderer that can be called with .draw() in the [[ExcaliburGraphicsContext]] */ diff --git a/src/engine/Graphics/Context/screen-pass-painter/screen-pass-painter.ts b/src/engine/Graphics/Context/screen-pass-painter/screen-pass-painter.ts index 4e98d1cc..9b85cf54 100644 --- a/src/engine/Graphics/Context/screen-pass-painter/screen-pass-painter.ts +++ b/src/engine/Graphics/Context/screen-pass-painter/screen-pass-painter.ts @@ -1,4 +1,3 @@ - import screenVertex from './screen-vertex.glsl'; import screenFragment from './screen-fragment.glsl'; import { Shader } from '../shader'; @@ -28,13 +27,9 @@ export class ScreenPassPainter { type: 'static', // clip space quad + uv since we don't need a camera data: new Float32Array([ - -1, -1, 0, 0, - -1, 1, 0, 1, - 1, -1, 1, 0, + -1, -1, 0, 0, -1, 1, 0, 1, 1, -1, 1, 0, - 1, -1, 1, 0, - -1, 1, 0, 1, - 1, 1, 1, 1 + 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1 ]) }); this._layout = new VertexLayout({ @@ -62,4 +57,4 @@ export class ScreenPassPainter { this._layout.use(); gl.drawArrays(gl.TRIANGLES, 0, 6); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/shader.ts b/src/engine/Graphics/Context/shader.ts index b7f6f687..547cd5ea 100644 --- a/src/engine/Graphics/Context/shader.ts +++ b/src/engine/Graphics/Context/shader.ts @@ -6,31 +6,33 @@ import { getAttributeComponentSize, getAttributePointerType } from './webgl-util * List of the possible glsl uniform types */ export type UniformTypeNames = - 'uniform1f' | - 'uniform1i' | - 'uniform2f' | - 'uniform2i' | - 'uniform3f' | - 'uniform3i' | - 'uniform4f' | - 'uniform4i' | - 'uniform1fv' | - 'uniform1iv' | - 'uniform2fv' | - 'uniform2iv' | - 'uniform3fv' | - 'uniform3iv' | - 'uniform4fv' | - 'uniform4iv' | - 'uniformMatrix2fv' | - 'uniformMatrix3fv' | - 'uniformMatrix4fv'; - -type RemoveFirstFromTuple = - T['length'] extends 0 ? undefined : - (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : []) - -type UniformParameters = RemoveFirstFromTuple> + | 'uniform1f' + | 'uniform1i' + | 'uniform2f' + | 'uniform2i' + | 'uniform3f' + | 'uniform3i' + | 'uniform4f' + | 'uniform4i' + | 'uniform1fv' + | 'uniform1iv' + | 'uniform2fv' + | 'uniform2iv' + | 'uniform3fv' + | 'uniform3iv' + | 'uniform4fv' + | 'uniform4iv' + | 'uniformMatrix2fv' + | 'uniformMatrix3fv' + | 'uniformMatrix4fv'; + +type RemoveFirstFromTuple = T['length'] extends 0 + ? undefined + : ((...b: T) => void) extends (a: any, ...b: infer I) => void + ? I + : []; + +type UniformParameters = RemoveFirstFromTuple>; export interface UniformDefinition { name: string; @@ -38,7 +40,6 @@ export interface UniformDefinition { location: WebGLUniformLocation; } - export interface VertexAttributeDefinition { /** * string name of the attribute in the shader program, commonly `a_nameofmyvariable` @@ -383,8 +384,10 @@ export class Shader { throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`); } if (!this.isCurrentlyBound()) { - throw Error('Currently accessed shader instance is not the current active shader in WebGL,' + - ' must call `shader.use()` before setting uniforms'); + throw Error( + 'Currently accessed shader instance is not the current active shader in WebGL,' + + ' must call `shader.use()` before setting uniforms' + ); } const gl = this._gl; const location = gl.getUniformLocation(this.program, name); @@ -392,8 +395,10 @@ export class Shader { const args = [location, ...value]; this._gl[uniformType].apply(this._gl, args); } else { - throw Error(`Uniform ${uniformType}:${name} doesn\'t exist or is not used in the shader source code,`+ - ' unused uniforms are optimized away by most browsers'); + throw Error( + `Uniform ${uniformType}:${name} doesn\'t exist or is not used in the shader source code,` + + ' unused uniforms are optimized away by most browsers' + ); } } @@ -409,14 +414,17 @@ export class Shader { trySetUniform( uniformType: TUniformType, name: string, - ...value: UniformParameters): boolean { + ...value: UniformParameters + ): boolean { if (!this._compiled) { this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`); return false; } if (!this.isCurrentlyBound()) { - this._logger.warn('Currently accessed shader instance is not the current active shader in WebGL,' + - ' must call `shader.use()` before setting uniforms'); + this._logger.warn( + 'Currently accessed shader instance is not the current active shader in WebGL,' + + ' must call `shader.use()` before setting uniforms' + ); return false; } const gl = this._gl; @@ -476,11 +484,14 @@ export class Shader { const lines = source.split('\n'); const errorLineStart = errorInfo.search(/\d:\d/); const errorLineEnd = errorInfo.indexOf(' ', errorLineStart); - const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(':').map(v => Number(v)); + const [_, error2] = errorInfo + .slice(errorLineStart, errorLineEnd) + .split(':') + .map((v) => Number(v)); for (let i = 0; i < lines.length; i++) { - lines[i] = `${i+1}: ${lines[i]}${error2 === (i+1)? ' <----- ERROR!' : ''}`; + lines[i] = `${i + 1}: ${lines[i]}${error2 === i + 1 ? ' <----- ERROR!' : ''}`; } return '\n\nSource:\n' + lines.join('\n'); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/texture-loader.ts b/src/engine/Graphics/Context/texture-loader.ts index c437255a..84187b6f 100644 --- a/src/engine/Graphics/Context/texture-loader.ts +++ b/src/engine/Graphics/Context/texture-loader.ts @@ -27,7 +27,7 @@ export class TextureLoader { * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]] */ public static filtering: ImageFiltering = ImageFiltering.Blended; - public static wrapping: ImageWrapConfiguration = {x: ImageWrapping.Clamp, y: ImageWrapping.Clamp}; + public static wrapping: ImageWrapConfiguration = { x: ImageWrapping.Clamp, y: ImageWrapping.Clamp }; private _gl: WebGL2RenderingContext; @@ -64,7 +64,7 @@ export class TextureLoader { return null; } - const { filtering, wrapping } = {...options}; + const { filtering, wrapping } = { ...options }; let tex: WebGLTexture = null; // If reuse the texture if it's from the same source @@ -105,7 +105,7 @@ export class TextureLoader { }; } } - const { x: xWrap, y: yWrap} = (wrappingConfig ?? TextureLoader.wrapping); + const { x: xWrap, y: yWrap } = wrappingConfig ?? TextureLoader.wrapping; switch (xWrap) { case ImageWrapping.Clamp: gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); @@ -168,18 +168,20 @@ export class TextureLoader { const originalSrc = image.dataset.originalSrc ?? 'internal canvas bitmap'; if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) { TextureLoader._LOGGER.error( - `The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of `+ - `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image ` - +`for excalibur to render properly.\n\nImages will likely render as black rectangles.\n\n`+ - `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`); + `The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of ` + + `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image ` + + `for excalibur to render properly.\n\nImages will likely render as black rectangles.\n\n` + + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits` + ); return false; } else if (image.width > 4096 || image.height > 4096) { // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits TextureLoader._LOGGER.warn( - `The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, `+ - `it is recommended you resize images to a maximum (4096x4096).\n\n` + - `Images will likely render as black rectangles on some mobile platforms.\n\n` + - `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`); + `The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, ` + + `it is recommended you resize images to a maximum (4096x4096).\n\n` + + `Images will likely render as black rectangles on some mobile platforms.\n\n` + + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits` + ); } return true; } diff --git a/src/engine/Graphics/Context/vertex-buffer.ts b/src/engine/Graphics/Context/vertex-buffer.ts index eb2349e5..667cba82 100644 --- a/src/engine/Graphics/Context/vertex-buffer.ts +++ b/src/engine/Graphics/Context/vertex-buffer.ts @@ -2,7 +2,7 @@ export interface VertexBufferOptions { /** * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts. */ - gl: WebGL2RenderingContext, + gl: WebGL2RenderingContext; /** * Size in number of floats, so [4.2, 4.0, 2.1] is size = 3 * @@ -19,7 +19,7 @@ export interface VertexBufferOptions { /** * Optionally pass pre-seeded data, size parameter is ignored */ - data?: Float32Array + data?: Float32Array; } /** @@ -97,4 +97,4 @@ export class VertexBuffer { gl.deleteBuffer(this.buffer); this._gl = null; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/vertex-layout.ts b/src/engine/Graphics/Context/vertex-layout.ts index f8137d84..9fbd0e5a 100644 --- a/src/engine/Graphics/Context/vertex-layout.ts +++ b/src/engine/Graphics/Context/vertex-layout.ts @@ -3,12 +3,11 @@ import { Shader, VertexAttributeDefinition } from './shader'; import { VertexBuffer } from './vertex-buffer'; import { getGLTypeFromSource, getGlTypeSizeBytes, isAttributeInSource } from './webgl-util'; - export interface VertexLayoutOptions { /** * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts. */ - gl: WebGL2RenderingContext, + gl: WebGL2RenderingContext; /** * Shader that this layout will be for, if null you must set a shader before using it. */ @@ -16,19 +15,19 @@ export interface VertexLayoutOptions { /** * Vertex buffer to use for vertex data */ - vertexBuffer: VertexBuffer, + vertexBuffer: VertexBuffer; /** * Specify the attributes that will exist in the vertex buffer * * **Important** must specify them in the order that they will be in the vertex buffer!! */ - attributes: [name: string, numberOfComponents: number][], + attributes: [name: string, numberOfComponents: number][]; /** * Optionally suppress any warnings out of vertex layouts * * **BEWARE** this may cause you to have issues go unnoticed */ - suppressWarnings?: boolean + suppressWarnings?: boolean; } /** @@ -58,7 +57,7 @@ export class VertexLayout { } constructor(options: VertexLayoutOptions) { - const {gl, shader, vertexBuffer, attributes, suppressWarnings } = options; + const { gl, shader, vertexBuffer, attributes, suppressWarnings } = options; this._gl = gl; this._vertexBuffer = vertexBuffer; this._attributes = attributes; @@ -111,17 +110,21 @@ export class VertexLayout { const attrib = shaderAttributes[attribute[0]]; if (!attrib) { if (!isAttributeInSource(this._shader.vertexSource, attribute[0])) { - throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}`+ - ` not found in the shader source code:\n ${this._shader.vertexSource}`); + throw Error( + `The attribute named: ${attribute[0]} size ${attribute[1]}` + + ` not found in the shader source code:\n ${this._shader.vertexSource}` + ); } if (!this._suppressWarnings) { - this._logger.warn(`The attribute named: ${attribute[0]} size ${attribute[1]}`+ - ` not found in the compiled shader. This is possibly a bug:\n` + - ` 1. Not a bug, but should remove unused code - attribute "${attribute[0]}" is unused in` + - ` vertex/fragment and has been automatically removed by glsl compiler.\n` + - ` 2. Definitely a bug, attribute "${attribute[0]}" in layout has been mistyped or is missing` + - ` in shader, check vertex/fragment source.`); + this._logger.warn( + `The attribute named: ${attribute[0]} size ${attribute[1]}` + + ` not found in the compiled shader. This is possibly a bug:\n` + + ` 1. Not a bug, but should remove unused code - attribute "${attribute[0]}" is unused in` + + ` vertex/fragment and has been automatically removed by glsl compiler.\n` + + ` 2. Definitely a bug, attribute "${attribute[0]}" in layout has been mistyped or is missing` + + ` in shader, check vertex/fragment source.` + ); } const glType = getGLTypeFromSource(this._gl, this._shader.vertexSource, attribute[0]); @@ -137,8 +140,10 @@ export class VertexLayout { } if (attrib) { if (attrib.size !== attribute[1]) { - throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],` - +` doesn\'t match shader source size ${attrib.size}:\n ${this._shader.vertexSource}`); + throw Error( + `VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],` + + ` doesn\'t match shader source size ${attrib.size}:\n ${this._shader.vertexSource}` + ); } this._layout.push(attrib); } @@ -153,11 +158,12 @@ export class VertexLayout { } if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) { - this._logger.warn(`The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer` - +` (${this._vertexBuffer.bufferData.length})`); + this._logger.warn( + `The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer` + + ` (${this._vertexBuffer.bufferData.length})` + ); } - // create VAO const gl = this._gl; this._vao = gl.createVertexArray(); @@ -166,7 +172,8 @@ export class VertexLayout { let offset = 0; for (const vert of this._layout) { - if (vert.location !== -1) { // skip unused attributes + if (vert.location !== -1) { + // skip unused attributes gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset); gl.enableVertexAttribArray(vert.location); } @@ -197,4 +204,4 @@ export class VertexLayout { } gl.bindVertexArray(this._vao); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Context/webgl-util.ts b/src/engine/Graphics/Context/webgl-util.ts index 088c4cdd..f03f28ff 100644 --- a/src/engine/Graphics/Context/webgl-util.ts +++ b/src/engine/Graphics/Context/webgl-util.ts @@ -76,7 +76,6 @@ export function getGLTypeFromSource(gl: WebGLRenderingContext, source: string, v } } - /** * Based on the type return the number of attribute components * @@ -134,4 +133,4 @@ export function getAttributePointerType(gl: WebGLRenderingContext, type: number) default: return gl.FLOAT; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Debug.ts b/src/engine/Graphics/Debug.ts index a76400e3..ae7f4efe 100644 --- a/src/engine/Graphics/Debug.ts +++ b/src/engine/Graphics/Debug.ts @@ -16,20 +16,20 @@ export class Debug { } static drawPoint(point: Vector, options?: PointGraphicsOptions) { - Debug.draw(ctx => { + Debug.draw((ctx) => { ctx.debug.drawPoint(point, options); }); } static drawLine(start: Vector, end: Vector, options?: LineGraphicsOptions) { - Debug.draw(ctx => { + Debug.draw((ctx) => { ctx.debug.drawLine(start, end, options); }); } static drawLines(points: Vector[], options?: LineGraphicsOptions) { if (points.length > 1) { - Debug.draw(ctx => { + Debug.draw((ctx) => { for (let i = 0; i < points.length - 1; i++) { ctx.debug.drawLine(points[i], points[i + 1], options); } @@ -38,14 +38,14 @@ export class Debug { } static drawText(text: string, pos: Vector) { - Debug.draw(ctx => { + Debug.draw((ctx) => { ctx.debug.drawText(text, pos); }); } static drawPolygon(points: Vector[], options?: { color?: Color }) { if (points.length > 1) { - Debug.draw(ctx => { + Debug.draw((ctx) => { const firstPoint = points[0]; const polygon = [...points, firstPoint]; for (let i = 0; i < polygon.length - 1; i++) { @@ -55,29 +55,33 @@ export class Debug { } } - static drawCircle(center: Vector, radius: number, options?: { - color?: Color, - strokeColor?: Color, - width?: number - }) { - const { color, strokeColor, width} = { + static drawCircle( + center: Vector, + radius: number, + options?: { + color?: Color; + strokeColor?: Color; + width?: number; + } + ) { + const { color, strokeColor, width } = { color: Color.Black, strokeColor: undefined, width: undefined, ...options }; - Debug.draw(ctx => { + Debug.draw((ctx) => { ctx.drawCircle(center, radius, color, strokeColor, width); }); } static drawBounds(boundingBox: BoundingBox, options?: { color?: Color }): void { - Debug.draw(ctx => { + Debug.draw((ctx) => { ctx.debug.drawRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height, options); }); } - static drawRay(ray: Ray, options?: { distance?: number, color?: Color }) { + static drawRay(ray: Ray, options?: { distance?: number; color?: Color }) { const { distance, color } = { color: Color.Blue, distance: 10, @@ -104,4 +108,4 @@ export class Debug { static clear() { Debug._drawCalls.length = 0; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/DebugGraphicsComponent.ts b/src/engine/Graphics/DebugGraphicsComponent.ts index 871d6b93..601f9256 100644 --- a/src/engine/Graphics/DebugGraphicsComponent.ts +++ b/src/engine/Graphics/DebugGraphicsComponent.ts @@ -2,7 +2,6 @@ import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext'; import { DebugConfig } from '../Debug'; import { Component } from '../EntityComponentSystem/Component'; - /** * Provide arbitrary drawing for the purposes of debugging your game * @@ -12,7 +11,8 @@ import { Component } from '../EntityComponentSystem/Component'; export class DebugGraphicsComponent extends Component { constructor( public draw: (ctx: ExcaliburGraphicsContext, debugFlags: DebugConfig) => void, - public useTransform = true) { + public useTransform = true + ) { super(); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Filtering.ts b/src/engine/Graphics/Filtering.ts index 0801692e..040f941b 100644 --- a/src/engine/Graphics/Filtering.ts +++ b/src/engine/Graphics/Filtering.ts @@ -1,9 +1,7 @@ - /** * Describes the different image filtering modes */ export enum ImageFiltering { - /** * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics. * @@ -22,8 +20,11 @@ export enum ImageFiltering { */ export function parseImageFiltering(val: string): ImageFiltering | null { switch (val) { - case ImageFiltering.Pixel: return ImageFiltering.Pixel; - case ImageFiltering.Blended: return ImageFiltering.Blended; - default: return null; + case ImageFiltering.Pixel: + return ImageFiltering.Pixel; + case ImageFiltering.Blended: + return ImageFiltering.Blended; + default: + return null; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Font.ts b/src/engine/Graphics/Font.ts index b5b2f801..c962a742 100644 --- a/src/engine/Graphics/Font.ts +++ b/src/engine/Graphics/Font.ts @@ -66,10 +66,10 @@ export class Font extends Graphic implements FontRenderer { direction: this.direction, shadow: this.shadow ? { - blur: this.shadow.blur, - offset: this.shadow.offset, - color: this.shadow.color - } + blur: this.shadow.blur, + offset: this.shadow.offset, + color: this.shadow.color + } : null }); } diff --git a/src/engine/Graphics/FontTextInstance.ts b/src/engine/Graphics/FontTextInstance.ts index 62c6e8eb..4b45e6ed 100644 --- a/src/engine/Graphics/FontTextInstance.ts +++ b/src/engine/Graphics/FontTextInstance.ts @@ -13,7 +13,12 @@ export class FontTextInstance { public disposed: boolean = false; private _lastHashCode: string; - constructor(public readonly font: Font, public readonly text: string, public readonly color: Color, public readonly maxWidth?: number) { + constructor( + public readonly font: Font, + public readonly text: string, + public readonly color: Color, + public readonly maxWidth?: number + ) { this.canvas = document.createElement('canvas'); this.ctx = this.canvas.getContext('2d'); this.dimensions = this.measureText(text); @@ -59,7 +64,7 @@ export class FontTextInstance { private _setDimension(textBounds: BoundingBox, bitmap: CanvasRenderingContext2D) { let lineHeightRatio = 1; if (this.font.lineHeight) { - lineHeightRatio = (this.font.lineHeight/this.font.size); + lineHeightRatio = this.font.lineHeight / this.font.size; } // Changing the width and height clears the context properties // We double the bitmap width to account for all possible alignment diff --git a/src/engine/Graphics/Graphic.ts b/src/engine/Graphics/Graphic.ts index 7c24e6db..91819d36 100644 --- a/src/engine/Graphics/Graphic.ts +++ b/src/engine/Graphics/Graphic.ts @@ -69,7 +69,6 @@ export abstract class Graphic { */ public showDebug: boolean = false; - private _flipHorizontal = false; /** * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis) @@ -166,7 +165,7 @@ export abstract class Graphic { rotation: this.rotation, opacity: this.opacity, scale: this.scale ? this.scale.clone() : null, - tint: this.tint ? this.tint.clone(): null + tint: this.tint ? this.tint.clone() : null }; } diff --git a/src/engine/Graphics/GraphicsComponent.ts b/src/engine/Graphics/GraphicsComponent.ts index 7fa047d8..e381b61b 100644 --- a/src/engine/Graphics/GraphicsComponent.ts +++ b/src/engine/Graphics/GraphicsComponent.ts @@ -57,7 +57,7 @@ export interface GraphicsComponentOptions { /** * List of graphics and optionally the options per graphic */ - graphics?: { [graphicName: string]: Graphic | { graphic: Graphic, options: GraphicsShowOptions } }; + graphics?: { [graphicName: string]: Graphic | { graphic: Graphic; options: GraphicsShowOptions } }; /** * Optional offset in absolute pixels to shift all graphics in this component from each graphic's anchor (default is top left corner) @@ -112,7 +112,6 @@ export class GraphicsComponent extends Component { */ public opacity: number = 1; - private _offset: Vector = Vector.Zero; /** @@ -269,7 +268,7 @@ export class GraphicsComponent extends Component { } this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet; - this._options[name] = this.copyGraphics ? {...optionsToSet} : optionsToSet; + this._options[name] = this.copyGraphics ? { ...optionsToSet } : optionsToSet; if (name === 'default') { this.use('default'); } @@ -320,7 +319,8 @@ export class GraphicsComponent extends Component { this._options[this._current] = options; if (!(this._current in this._graphics)) { this._logger.warn( - `Graphic ${this._current} is not registered with the graphics component owned by ${this.owner?.name}. Nothing will be drawn.`); + `Graphic ${this._current} is not registered with the graphics component owned by ${this.owner?.name}. Nothing will be drawn.` + ); } } this.recalculateBounds(); @@ -358,8 +358,8 @@ export class GraphicsComponent extends Component { offset = options.offset; } const bounds = graphic.localBounds; - const offsetX = -bounds.width * anchor.x + offset.x; - const offsetY = -bounds.height * anchor.y + offset.y; + const offsetX = -bounds.width * anchor.x + offset.x; + const offsetY = -bounds.height * anchor.y + offset.y; if (graphic instanceof GraphicsGroup && !graphic.useAnchor) { bb = graphic?.localBounds.combine(bb); } else { @@ -404,11 +404,10 @@ export class GraphicsComponent extends Component { } } - public clone(): GraphicsComponent { const graphics = new GraphicsComponent(); graphics._graphics = { ...this._graphics }; - graphics._options = {... this._options}; + graphics._options = { ...this._options }; graphics.offset = this.offset.clone(); graphics.opacity = this.opacity; graphics.anchor = this.anchor.clone(); diff --git a/src/engine/Graphics/GraphicsSystem.ts b/src/engine/Graphics/GraphicsSystem.ts index 88ab1306..ccd773b6 100644 --- a/src/engine/Graphics/GraphicsSystem.ts +++ b/src/engine/Graphics/GraphicsSystem.ts @@ -34,13 +34,13 @@ export class GraphicsSystem extends System { constructor(public world: World) { super(); this.query = this.world.query([TransformComponent, GraphicsComponent]); - this.query.entityAdded$.subscribe(e => { + this.query.entityAdded$.subscribe((e) => { const tx = e.get(TransformComponent); this._sortedTransforms.push(tx); tx.zIndexChanged$.subscribe(this._zIndexUpdate); this._zHasChanged = true; }); - this.query.entityRemoved$.subscribe(e => { + this.query.entityRemoved$.subscribe((e) => { const tx = e.get(TransformComponent); tx.zIndexChanged$.unsubscribe(this._zIndexUpdate); const index = this._sortedTransforms.indexOf(tx); @@ -142,7 +142,7 @@ export class GraphicsSystem extends System { // TODO remove this hack on the particle redo // Remove this line after removing the wallaby import - const particleOpacity = (entity instanceof Particle) ? entity.opacity : 1; + const particleOpacity = entity instanceof Particle ? entity.opacity : 1; this._graphicsContext.opacity *= graphics.opacity * particleOpacity; // Draw the graphics component @@ -209,10 +209,7 @@ export class GraphicsSystem extends System { graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical; } - graphic?.draw( - this._graphicsContext, - offsetX, - offsetY); + graphic?.draw(this._graphicsContext, offsetX, offsetY); if (flipHorizontal || flipVertical) { graphic.flipHorizontal = oldFlipHorizontal; @@ -260,9 +257,7 @@ export class GraphicsSystem extends System { const optionalBody = ancestor?.get(BodyComponent); let tx = transform.get(); if (optionalBody) { - if (this._engine.fixedUpdateFps && - optionalBody.__oldTransformCaptured && - optionalBody.enableFixedUpdateInterpolate) { + if (this._engine.fixedUpdateFps && optionalBody.__oldTransformCaptured && optionalBody.enableFixedUpdateInterpolate) { // Interpolate graphics if needed const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps); tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform); diff --git a/src/engine/Graphics/ImageSource.ts b/src/engine/Graphics/ImageSource.ts index 083c5108..8e53fc69 100644 --- a/src/engine/Graphics/ImageSource.ts +++ b/src/engine/Graphics/ImageSource.ts @@ -93,7 +93,7 @@ export class ImageSource implements Loadable { if (typeof bustCacheOrOptions === 'boolean') { bustCache = bustCacheOrOptions; } else { - ({ filtering, wrapping, bustCache } = {...bustCacheOrOptions}); + ({ filtering, wrapping, bustCache } = { ...bustCacheOrOptions }); } this._resource = new Resource(path, 'blob', bustCache); this.filtering = filtering ?? this.filtering; diff --git a/src/engine/Graphics/Line.ts b/src/engine/Graphics/Line.ts index 3317f113..2cf397d1 100644 --- a/src/engine/Graphics/Line.ts +++ b/src/engine/Graphics/Line.ts @@ -61,4 +61,4 @@ export class Line extends Graphic { thickness: this.thickness }); } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/OffscreenSystem.ts b/src/engine/Graphics/OffscreenSystem.ts index e10dc820..60822266 100644 --- a/src/engine/Graphics/OffscreenSystem.ts +++ b/src/engine/Graphics/OffscreenSystem.ts @@ -19,7 +19,6 @@ export class OffscreenSystem extends System { private _worldBounds: BoundingBox; query: Query; - constructor(public world: World) { super(); this.query = this.world.query([TransformComponent, GraphicsComponent]); @@ -78,5 +77,4 @@ export class OffscreenSystem extends System { return false; } } - -} \ No newline at end of file +} diff --git a/src/engine/Graphics/ParallaxComponent.ts b/src/engine/Graphics/ParallaxComponent.ts index ac5559c7..b462bcbb 100644 --- a/src/engine/Graphics/ParallaxComponent.ts +++ b/src/engine/Graphics/ParallaxComponent.ts @@ -2,11 +2,10 @@ import { Component } from '../EntityComponentSystem/Component'; import { vec, Vector } from '../Math/vector'; export class ParallaxComponent extends Component { - parallaxFactor = vec(1.0, 1.0); constructor(parallaxFactor?: Vector) { super(); this.parallaxFactor = parallaxFactor ?? this.parallaxFactor; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/PostProcessor/ColorBlindnessMode.ts b/src/engine/Graphics/PostProcessor/ColorBlindnessMode.ts index 60da6b31..c6a542ee 100644 --- a/src/engine/Graphics/PostProcessor/ColorBlindnessMode.ts +++ b/src/engine/Graphics/PostProcessor/ColorBlindnessMode.ts @@ -1,5 +1,3 @@ - - export enum ColorBlindnessMode { Protanope = 'Protanope', Deuteranope = 'Deuteranope', diff --git a/src/engine/Graphics/PostProcessor/ColorBlindnessPostProcessor.ts b/src/engine/Graphics/PostProcessor/ColorBlindnessPostProcessor.ts index 7a6dbe4e..756b9892 100644 --- a/src/engine/Graphics/PostProcessor/ColorBlindnessPostProcessor.ts +++ b/src/engine/Graphics/PostProcessor/ColorBlindnessPostProcessor.ts @@ -8,7 +8,10 @@ import { ScreenShader } from './ScreenShader'; export class ColorBlindnessPostProcessor implements PostProcessor { private _shader: ScreenShader; private _simulate = false; - constructor(private _colorBlindnessMode: ColorBlindnessMode, simulate = false) { + constructor( + private _colorBlindnessMode: ColorBlindnessMode, + simulate = false + ) { this._simulate = simulate; } @@ -48,7 +51,6 @@ export class ColorBlindnessPostProcessor implements PostProcessor { set simulate(value: boolean) { this._simulate = value; if (this._shader) { - const shader = this._shader.getShader(); shader.use(); shader.setUniformBoolean('u_simulate', value); diff --git a/src/engine/Graphics/PostProcessor/PostProcessor.ts b/src/engine/Graphics/PostProcessor/PostProcessor.ts index 85a0359c..b56c24f8 100644 --- a/src/engine/Graphics/PostProcessor/PostProcessor.ts +++ b/src/engine/Graphics/PostProcessor/PostProcessor.ts @@ -1,8 +1,6 @@ - import { VertexLayout } from '../Context/vertex-layout'; import { Shader } from '../Context/shader'; - /** * PostProcessors can be used to apply a shader to the entire screen. It is recommended * you use the [[ScreenShader]] to build your post processor shader. diff --git a/src/engine/Graphics/PostProcessor/ScreenShader.ts b/src/engine/Graphics/PostProcessor/ScreenShader.ts index cae0ca4c..7bb7fb5f 100644 --- a/src/engine/Graphics/PostProcessor/ScreenShader.ts +++ b/src/engine/Graphics/PostProcessor/ScreenShader.ts @@ -34,13 +34,9 @@ export class ScreenShader { type: 'static', // clip space quad + uv since we don't need a camera data: new Float32Array([ - -1, -1, 0, 0, - -1, 1, 0, 1, - 1, -1, 1, 0, + -1, -1, 0, 0, -1, 1, 0, 1, 1, -1, 1, 0, - 1, -1, 1, 0, - -1, 1, 0, 1, - 1, 1, 1, 1 + 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1 ]) }); this._layout = new VertexLayout({ @@ -61,4 +57,4 @@ export class ScreenShader { public getLayout() { return this._layout; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Sprite.ts b/src/engine/Graphics/Sprite.ts index dab36955..ff325b46 100644 --- a/src/engine/Graphics/Sprite.ts +++ b/src/engine/Graphics/Sprite.ts @@ -107,8 +107,8 @@ export class Sprite extends Graphic { } else { this._logger.warnOnce( `ImageSource ${this.image.path}` + - ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\n\n` + - `Read https://excaliburjs.com/docs/imagesource for more information.` + ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\n\n` + + `Read https://excaliburjs.com/docs/imagesource for more information.` ); } } diff --git a/src/engine/Graphics/SpriteSheet.ts b/src/engine/Graphics/SpriteSheet.ts index 8bd1ba0c..a6840646 100644 --- a/src/engine/Graphics/SpriteSheet.ts +++ b/src/engine/Graphics/SpriteSheet.ts @@ -11,13 +11,13 @@ export interface SpriteSheetSpacingDimensions { * The starting point to offset and start slicing the sprite sheet from the top left of the image. * Default is (0, 0) */ - originOffset?: { x?: number, y?: number }; + originOffset?: { x?: number; y?: number }; /** * The margin between sprites. * Default is (0, 0) */ - margin?: {x?: number, y?: number}; + margin?: { x?: number; y?: number }; } /** @@ -143,13 +143,13 @@ export class SpriteSheet { * @param options */ public static fromImageSourceWithSourceViews(options: SpriteSheetSparseOptions): SpriteSheet { - const sprites: Sprite[] = options.sourceViews.map(sourceView => { + const sprites: Sprite[] = options.sourceViews.map((sourceView) => { return new Sprite({ image: options.image, sourceView }); }); - return new SpriteSheet({sprites}); + return new SpriteSheet({ sprites }); } /** @@ -190,8 +190,8 @@ export class SpriteSheet { grid: { rows, columns: cols, spriteWidth, spriteHeight }, spacing: { originOffset, margin } } = options; - const offsetDefaults = { x: 0, y: 0, ...originOffset}; - const marginDefaults = { x: 0, y: 0, ...margin}; + const offsetDefaults = { x: 0, y: 0, ...originOffset }; + const marginDefaults = { x: 0, y: 0, ...margin }; for (let x = 0; x < cols; x++) { for (let y = 0; y < rows; y++) { sprites[x + y * cols] = new Sprite({ @@ -215,7 +215,7 @@ export class SpriteSheet { public clone(): SpriteSheet { return new SpriteSheet({ - sprites: this.sprites.map(sprite => sprite.clone()), + sprites: this.sprites.map((sprite) => sprite.clone()), rows: this.rows, columns: this.columns }); diff --git a/src/engine/Graphics/TransformInterpolation.ts b/src/engine/Graphics/TransformInterpolation.ts index a29a6bf2..c87141f9 100644 --- a/src/engine/Graphics/TransformInterpolation.ts +++ b/src/engine/Graphics/TransformInterpolation.ts @@ -21,12 +21,8 @@ export function blendTransform(oldTx: Transform, newTx: Transform, blend: number let interpolatedScale = newTx.scale; let interpolatedRotation = newTx.rotation; - interpolatedPos = newTx.pos.scale(blend).add( - oldTx.pos.scale(1.0 - blend) - ); - interpolatedScale = newTx.scale.scale(blend).add( - oldTx.scale.scale(1.0 - blend) - ); + interpolatedPos = newTx.pos.scale(blend).add(oldTx.pos.scale(1.0 - blend)); + interpolatedScale = newTx.scale.scale(blend).add(oldTx.scale.scale(1.0 - blend)); // Rotational lerp https://stackoverflow.com/a/30129248 const cosine = (1.0 - blend) * Math.cos(oldTx.rotation) + blend * Math.cos(newTx.rotation); const sine = (1.0 - blend) * Math.sin(oldTx.rotation) + blend * Math.sin(newTx.rotation); @@ -45,12 +41,8 @@ export function blendGlobalTransform(oldTx: Transform, newTx: Transform, blend: let interpolatedScale = newTx.globalScale; let interpolatedRotation = newTx.globalRotation; - interpolatedPos = newTx.globalPos.scale(blend).add( - oldTx.globalPos.scale(1.0 - blend) - ); - interpolatedScale = newTx.globalScale.scale(blend).add( - oldTx.globalScale.scale(1.0 - blend) - ); + interpolatedPos = newTx.globalPos.scale(blend).add(oldTx.globalPos.scale(1.0 - blend)); + interpolatedScale = newTx.globalScale.scale(blend).add(oldTx.globalScale.scale(1.0 - blend)); // Rotational lerp https://stackoverflow.com/a/30129248 const cosine = (1.0 - blend) * Math.cos(oldTx.globalRotation) + blend * Math.cos(newTx.globalRotation); const sine = (1.0 - blend) * Math.sin(oldTx.globalRotation) + blend * Math.sin(newTx.globalRotation); @@ -59,4 +51,4 @@ export function blendGlobalTransform(oldTx: Transform, newTx: Transform, blend: const tx = target ?? new Transform(); tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale); return tx; -} \ No newline at end of file +} diff --git a/src/engine/Graphics/Wrapping.ts b/src/engine/Graphics/Wrapping.ts index 324c21a3..78efa4be 100644 --- a/src/engine/Graphics/Wrapping.ts +++ b/src/engine/Graphics/Wrapping.ts @@ -1,9 +1,7 @@ - /** * Describes the different image wrapping modes */ export enum ImageWrapping { - Clamp = 'Clamp', Repeat = 'Repeat', @@ -16,9 +14,13 @@ export enum ImageWrapping { */ export function parseImageWrapping(val: string): ImageWrapping { switch (val) { - case ImageWrapping.Clamp: return ImageWrapping.Clamp; - case ImageWrapping.Repeat: return ImageWrapping.Repeat; - case ImageWrapping.Mirror: return ImageWrapping.Mirror; - default: return ImageWrapping.Clamp; + case ImageWrapping.Clamp: + return ImageWrapping.Clamp; + case ImageWrapping.Repeat: + return ImageWrapping.Repeat; + case ImageWrapping.Mirror: + return ImageWrapping.Mirror; + default: + return ImageWrapping.Clamp; } -} \ No newline at end of file +} diff --git a/src/engine/Graphics/index.ts b/src/engine/Graphics/index.ts index b3707a31..df5d2b8f 100644 --- a/src/engine/Graphics/index.ts +++ b/src/engine/Graphics/index.ts @@ -42,7 +42,6 @@ export * from './Context/texture-loader'; export * from './Filtering'; export * from './Wrapping'; - // Rendering export * from './Context/shader'; export * from './Context/vertex-buffer'; @@ -56,4 +55,4 @@ export * from './Debug'; // Util import * as webgl from './Context/webgl-util'; -export { webgl }; \ No newline at end of file +export { webgl }; diff --git a/src/engine/Id.ts b/src/engine/Id.ts index 5be83e7b..7e99b3bb 100644 --- a/src/engine/Id.ts +++ b/src/engine/Id.ts @@ -1,6 +1,6 @@ export type Id = { - type: T, - value: number + type: T; + value: number; }; /** @@ -8,4 +8,4 @@ export type Id = { */ export function createId(type: T, value: number): Id { return { type, value }; -}; +} diff --git a/src/engine/Input/Gamepad.ts b/src/engine/Input/Gamepad.ts index 585fbe63..9a6850f6 100644 --- a/src/engine/Input/Gamepad.ts +++ b/src/engine/Input/Gamepad.ts @@ -2,11 +2,11 @@ import { GamepadConnectEvent, GamepadDisconnectEvent, GamepadButtonEvent, Gamepa import { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter'; export type GamepadEvents = { - connect: GamepadConnectEvent, - disconnect: GamepadDisconnectEvent, - button: GamepadButtonEvent, - axis: GamepadAxisEvent -} + connect: GamepadConnectEvent; + disconnect: GamepadDisconnectEvent; + button: GamepadButtonEvent; + axis: GamepadAxisEvent; +}; export const GamepadEvents = { GamepadConnect: 'connect', @@ -277,7 +277,6 @@ export class Gamepads { clonedPad.updateAxes(i, pad.axes[i]); } - return clonedPad; } } @@ -372,7 +371,7 @@ export class Gamepad { if (value === 0 && this._buttons[buttonIndex]) { this._buttonsUp[buttonIndex] = 1; - // button was just pressed + // button was just pressed } else { this._buttonsDown[buttonIndex] = value; } diff --git a/src/engine/Input/Index.ts b/src/engine/Input/Index.ts index 8b9f63e7..7d757f44 100644 --- a/src/engine/Input/Index.ts +++ b/src/engine/Input/Index.ts @@ -43,7 +43,6 @@ export { CapturePointerConfig } from './CapturePointerConfig'; - export { /** * @deprecated ex.Input.NativePointerEvent import site will be removed in v0.29.0, use ex.NativePointerEvent @@ -156,4 +155,4 @@ export { * @deprecated ex.Input.GamepadConfiguration import site will be removed in v0.29.0, use ex.GamepadConfiguration */ GamepadConfiguration -} from './Gamepad'; \ No newline at end of file +} from './Gamepad'; diff --git a/src/engine/Input/InputHost.ts b/src/engine/Input/InputHost.ts index 3d0ce6a1..a6fdba78 100644 --- a/src/engine/Input/InputHost.ts +++ b/src/engine/Input/InputHost.ts @@ -5,9 +5,9 @@ import { Keyboard } from './Keyboard'; import { PointerEventReceiver } from './PointerEventReceiver'; export interface InputHostOptions { - pointerTarget: Document | HTMLCanvasElement - grabWindowFocus: boolean, - engine: Engine + pointerTarget: Document | HTMLCanvasElement; + grabWindowFocus: boolean; + engine: Engine; } export class InputHost { @@ -24,8 +24,8 @@ export class InputHost { this.pointers = new PointerEventReceiver(pointerTarget, engine); this.gamepads = new Gamepads(); - this.keyboard.init({grabWindowFocus}); - this.pointers.init({grabWindowFocus}); + this.keyboard.init({ grabWindowFocus }); + this.pointers.init({ grabWindowFocus }); this.gamepads.init(); this.inputMapper = new InputMapper({ keyboard: this.keyboard, @@ -52,4 +52,4 @@ export class InputHost { this.gamepads.update(); } } -} \ No newline at end of file +} diff --git a/src/engine/Input/InputMapper.ts b/src/engine/Input/InputMapper.ts index 293d8ec6..c6e9e2b3 100644 --- a/src/engine/Input/InputMapper.ts +++ b/src/engine/Input/InputMapper.ts @@ -13,7 +13,6 @@ export interface InputsOptions { * you need to allow multiple input sources to control a specific action. */ export class InputMapper { - private _handlers = new Map(); constructor(public inputs: InputsOptions) {} @@ -51,7 +50,8 @@ export class InputMapper { */ on( inputHandler: (inputs: InputsOptions) => TInputHandlerData | false, - commandHandler: (data: TInputHandlerData) => any) { + commandHandler: (data: TInputHandlerData) => any + ) { this._handlers.set(inputHandler, commandHandler); } -} \ No newline at end of file +} diff --git a/src/engine/Input/Keyboard.ts b/src/engine/Input/Keyboard.ts index 8064a786..2acbc6f2 100644 --- a/src/engine/Input/Keyboard.ts +++ b/src/engine/Input/Keyboard.ts @@ -185,20 +185,24 @@ export class KeyEvent extends Events.GameEvent { * @param value The key's typed value the browser detected * @param originalEvent The original keyboard event that Excalibur handled */ - constructor(public key: Keys, public value?: string, public originalEvent?: KeyboardEvent) { + constructor( + public key: Keys, + public value?: string, + public originalEvent?: KeyboardEvent + ) { super(); } } export interface KeyboardInitOptions { - global?: GlobalEventHandlers, - grabWindowFocus?: boolean + global?: GlobalEventHandlers; + grabWindowFocus?: boolean; } export type KeyEvents = { - press: KeyEvent, - hold: KeyEvent, - release: KeyEvent + press: KeyEvent; + hold: KeyEvent; + release: KeyEvent; }; export const KeyEvents = { @@ -294,7 +298,7 @@ export class Keyboard { this.events.emit('up', keyEvent); this.events.emit('release', keyEvent); } - this._keysUp = Array.from((new Set(this._keys.concat(this._keysUp)))); + this._keysUp = Array.from(new Set(this._keys.concat(this._keysUp))); this._keys.length = 0; }; @@ -390,16 +394,20 @@ export class Keyboard { */ public triggerEvent(type: 'down' | 'up', key: Keys, character?: string) { if (type === 'down') { - this._handleKeyDown(new KeyboardEvent('keydown', { - code: key, - key: character ?? null - })); + this._handleKeyDown( + new KeyboardEvent('keydown', { + code: key, + key: character ?? null + }) + ); } if (type === 'up') { - this._handleKeyUp(new KeyboardEvent('keyup', { - code: key, - key: character ?? null - })); + this._handleKeyUp( + new KeyboardEvent('keyup', { + code: key, + key: character ?? null + }) + ); } } } diff --git a/src/engine/Input/PointerComponent.ts b/src/engine/Input/PointerComponent.ts index aa035b43..99729538 100644 --- a/src/engine/Input/PointerComponent.ts +++ b/src/engine/Input/PointerComponent.ts @@ -40,4 +40,4 @@ export class PointerComponent extends Component { this.useGraphicsBounds = options?.useGraphicsBounds ?? this.useGraphicsBounds; this.localBounds = options?.localBounds; } -} \ No newline at end of file +} diff --git a/src/engine/Input/PointerEvent.ts b/src/engine/Input/PointerEvent.ts index 59fc2b3a..73971496 100644 --- a/src/engine/Input/PointerEvent.ts +++ b/src/engine/Input/PointerEvent.ts @@ -27,5 +27,6 @@ export class PointerEvent { public button: PointerButton, public pointerType: PointerType, public coordinates: GlobalCoordinates, - public nativeEvent: Event) { }; + public nativeEvent: Event + ) {} } diff --git a/src/engine/Input/PointerEventReceiver.ts b/src/engine/Input/PointerEventReceiver.ts index e453606f..ae1c11fc 100644 --- a/src/engine/Input/PointerEventReceiver.ts +++ b/src/engine/Input/PointerEventReceiver.ts @@ -14,18 +14,17 @@ import { PointerType } from './PointerType'; import { isCrossOriginIframe } from '../Util/IFrame'; import { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter'; - export type NativePointerEvent = globalThis.PointerEvent; export type NativeMouseEvent = globalThis.MouseEvent; export type NativeTouchEvent = globalThis.TouchEvent; export type NativeWheelEvent = globalThis.WheelEvent; export type PointerEvents = { - move: PointerEvent, - down: PointerEvent, - up: PointerEvent, - wheel: WheelEvent -} + move: PointerEvent; + down: PointerEvent; + up: PointerEvent; + wheel: WheelEvent; +}; export const PointerEvents = { Move: 'move', @@ -76,7 +75,10 @@ export class PointerEventReceiver { private _enabled = true; - constructor(public readonly target: GlobalEventHandlers & EventTarget, public engine: Engine) {} + constructor( + public readonly target: GlobalEventHandlers & EventTarget, + public engine: Engine + ) {} public toggleEnabled(enabled: boolean) { this._enabled = enabled; @@ -360,7 +362,7 @@ export class PointerEventReceiver { const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b) => a - b); // The index into sorted ids will be the new id, will always have an id - const id = currentPointerIds.findIndex(p => p === nativePointerId); + const id = currentPointerIds.findIndex((p) => p === nativePointerId); // Save the mapping so we can reverse it later this._activeNativePointerIdsToNormalized.set(nativePointerId, id); @@ -457,7 +459,7 @@ export class PointerEventReceiver { const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0; const deltaY = - ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0; + ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0; const deltaZ = ev.deltaZ || 0; let deltaMode = WheelDeltaMode.Pixel; @@ -484,17 +486,21 @@ export class PointerEventReceiver { const page = this.engine.screen.worldToPageCoordinates(pos); // Send an event to the event receiver if (window.PointerEvent) { - this._handle(new window.PointerEvent('pointer' + type, { - pointerId: 0, - clientX: page.x, - clientY: page.y - })); + this._handle( + new window.PointerEvent('pointer' + type, { + pointerId: 0, + clientX: page.x, + clientY: page.y + }) + ); } else { // Safari hack - this._handle(new window.MouseEvent('mouse' + type, { - clientX: page.x, - clientY: page.y - })); + this._handle( + new window.MouseEvent('mouse' + type, { + clientX: page.x, + clientY: page.y + }) + ); } // Force update pointer system @@ -532,4 +538,4 @@ export class PointerEventReceiver { return PointerType.Unknown; } } -} \ No newline at end of file +} diff --git a/src/engine/Input/PointerSystem.ts b/src/engine/Input/PointerSystem.ts index 4d0e8e72..ef725b57 100644 --- a/src/engine/Input/PointerSystem.ts +++ b/src/engine/Input/PointerSystem.ts @@ -1,14 +1,6 @@ import { ColliderComponent } from '../Collision/ColliderComponent'; import { Engine } from '../Engine'; -import { - System, - TransformComponent, - SystemType, - Entity, - World, - Query, - SystemPriority -} from '../EntityComponentSystem'; +import { System, TransformComponent, SystemType, Entity, World, Query, SystemPriority } from '../EntityComponentSystem'; import { GraphicsComponent } from '../Graphics/GraphicsComponent'; import { Scene } from '../Scene'; import { PointerComponent } from './PointerComponent'; @@ -35,7 +27,7 @@ export class PointerSystem extends System { constructor(public world: World) { super(); this.query = this.world.query([TransformComponent, PointerComponent]); - this.query.entityAdded$.subscribe(e => { + this.query.entityAdded$.subscribe((e) => { const tx = e.get(TransformComponent); this._sortedTransforms.push(tx); this._sortedEntities.push(tx.owner); @@ -43,7 +35,7 @@ export class PointerSystem extends System { this._zHasChanged = true; }); - this.query.entityRemoved$.subscribe(e => { + this.query.entityRemoved$.subscribe((e) => { const tx = e.get(TransformComponent); tx.zIndexChanged$.unsubscribe(this._zIndexUpdate); const index = this._sortedTransforms.indexOf(tx); @@ -88,31 +80,25 @@ export class PointerSystem extends System { this._sortedTransforms.sort((a, b) => { return b.z - a.z; }); - this._sortedEntities = this._sortedTransforms.map(t => t.owner); + this._sortedEntities = this._sortedTransforms.map((t) => t.owner); this._zHasChanged = false; } } - - public entityCurrentlyUnderPointer(entity: Entity, pointerId: number) { - return this.currentFrameEntityToPointers.has(entity.id) && - this.currentFrameEntityToPointers.get(entity.id).includes(pointerId); + return this.currentFrameEntityToPointers.has(entity.id) && this.currentFrameEntityToPointers.get(entity.id).includes(pointerId); } public entityWasUnderPointer(entity: Entity, pointerId: number) { - return this.lastFrameEntityToPointers.has(entity.id) && - this.lastFrameEntityToPointers.get(entity.id).includes(pointerId); + return this.lastFrameEntityToPointers.has(entity.id) && this.lastFrameEntityToPointers.get(entity.id).includes(pointerId); } public entered(entity: Entity, pointerId: number) { - return this.entityCurrentlyUnderPointer(entity, pointerId) && - !this.lastFrameEntityToPointers.has(entity.id); + return this.entityCurrentlyUnderPointer(entity, pointerId) && !this.lastFrameEntityToPointers.has(entity.id); } public left(entity: Entity, pointerId: number) { - return !this.currentFrameEntityToPointers.has(entity.id) && - this.entityWasUnderPointer(entity, pointerId); + return !this.currentFrameEntityToPointers.has(entity.id) && this.entityWasUnderPointer(entity, pointerId); } public addPointerToEntity(entity: Entity, pointerId: number) { @@ -132,11 +118,11 @@ export class PointerSystem extends System { this._dispatchEvents(this._sortedEntities); // Clear last frame's events - this._receivers.forEach(r => r.update()); + this._receivers.forEach((r) => r.update()); this.lastFrameEntityToPointers.clear(); this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers); this.currentFrameEntityToPointers.clear(); - this._receivers.forEach(r => r.clear()); + this._receivers.forEach((r) => r.clear()); } private _processPointerToEntity(entities: Entity[]) { @@ -152,7 +138,7 @@ export class PointerSystem extends System { // Pre-process find entities under pointers for (const entity of entities) { transform = entity.get(TransformComponent); - pointer = entity.get(PointerComponent) ?? new PointerComponent; + pointer = entity.get(PointerComponent) ?? new PointerComponent(); // If pointer bounds defined if (pointer.localBounds) { const pointerBounds = pointer.localBounds.transform(transform.get().matrix); @@ -252,11 +238,14 @@ export class PointerSystem extends System { } break; } - if (event.active && entity.active && - // leave can happen on move - (this.left(entity, event.pointerId) || + if ( + event.active && + entity.active && + // leave can happen on move + (this.left(entity, event.pointerId) || // or leave can happen on pointer up - (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up'))) { + (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up')) + ) { entity.events.emit('pointerleave', event as any); if (receiver.isDragging(event.pointerId)) { entity.events.emit('pointerdragleave', event as any); @@ -270,7 +259,7 @@ export class PointerSystem extends System { const receiver = this._engineReceiver; // cancel for (const event of receiver.currentFrameCancel) { - if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)){ + if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) { entity.events.emit('pointercancel', event as any); } } @@ -291,7 +280,7 @@ export class PointerSystem extends System { const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys()); const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys()); // Filter preserves z order - const entitiesWithEvents = entities.filter(e => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id)); + const entitiesWithEvents = entities.filter((e) => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id)); let lastMovePerPointer: Map; let lastUpPerPointer: Map; let lastDownPerPointer: Map; @@ -303,11 +292,7 @@ export class PointerSystem extends System { lastMovePerPointer = this._processMoveAndEmit(entity); - const lastUpDownMoveEvents = [ - ...lastMovePerPointer.values(), - ...lastDownPerPointer.values(), - ...lastUpPerPointer.values() - ]; + const lastUpDownMoveEvents = [...lastMovePerPointer.values(), ...lastDownPerPointer.values(), ...lastUpPerPointer.values()]; this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents); this._processCancelAndEmit(entity); @@ -315,4 +300,4 @@ export class PointerSystem extends System { this._processWheelAndEmit(entity); } } -} \ No newline at end of file +} diff --git a/src/engine/Input/WheelDeltaMode.ts b/src/engine/Input/WheelDeltaMode.ts index cee072ca..9c3be666 100644 --- a/src/engine/Input/WheelDeltaMode.ts +++ b/src/engine/Input/WheelDeltaMode.ts @@ -1,4 +1,3 @@ - export enum WheelDeltaMode { Pixel = 'Pixel', Line = 'Line', diff --git a/src/engine/Input/WheelEvent.ts b/src/engine/Input/WheelEvent.ts index 532dabe0..bc15916b 100644 --- a/src/engine/Input/WheelEvent.ts +++ b/src/engine/Input/WheelEvent.ts @@ -1,6 +1,5 @@ import { WheelDeltaMode } from './WheelDeltaMode'; - export class WheelEvent { public active = true; public cancel() { @@ -19,5 +18,5 @@ export class WheelEvent { public deltaZ: number, public deltaMode: WheelDeltaMode, public ev: Event - ) { } + ) {} } diff --git a/src/engine/Interfaces/Audio.ts b/src/engine/Interfaces/Audio.ts index 418b6d1a..c7681b1b 100644 --- a/src/engine/Interfaces/Audio.ts +++ b/src/engine/Interfaces/Audio.ts @@ -1,4 +1,3 @@ - /** * Represents an audio control implementation */ diff --git a/src/engine/Interfaces/Loadable.ts b/src/engine/Interfaces/Loadable.ts index 38486839..fa5a4ae4 100644 --- a/src/engine/Interfaces/Loadable.ts +++ b/src/engine/Interfaces/Loadable.ts @@ -13,7 +13,6 @@ export interface Loadable { */ load(): Promise; - /** * Returns true if the loadable is loaded */ diff --git a/src/engine/Label.ts b/src/engine/Label.ts index 4d23616d..de12cc54 100644 --- a/src/engine/Label.ts +++ b/src/engine/Label.ts @@ -29,7 +29,7 @@ export interface LabelOptions { /** * Specify a custom font */ - font?: Font + font?: Font; } /** @@ -99,7 +99,7 @@ export class Label extends Actor { */ constructor(options?: LabelOptions & ActorArgs) { super(options); - const {text, pos, x, y, spriteFont, font, color} = { text: '', ...options }; + const { text, pos, x, y, spriteFont, font, color } = { text: '', ...options }; this.pos = pos ?? (x && y ? vec(x, y) : this.pos); this.text = text ?? this.text; diff --git a/src/engine/Math/Index.ts b/src/engine/Math/Index.ts index b76fd2b8..9a02f063 100644 --- a/src/engine/Math/Index.ts +++ b/src/engine/Math/Index.ts @@ -9,4 +9,4 @@ export * from './global-coordinates'; export * from './line-segment'; export * from './projection'; export * from './ray'; -export * from './util'; \ No newline at end of file +export * from './util'; diff --git a/src/engine/Math/affine-matrix.ts b/src/engine/Math/affine-matrix.ts index f6d2bd0d..dfda5555 100644 --- a/src/engine/Math/affine-matrix.ts +++ b/src/engine/Math/affine-matrix.ts @@ -2,7 +2,6 @@ import { Matrix } from './matrix'; import { canonicalizeAngle, sign } from './util'; import { vec, Vector } from './vector'; - export class AffineMatrix { /** * | | | | @@ -245,15 +244,14 @@ export class AffineMatrix { const b23 = other.data[5]; // const b33 = 1; + result.data[0] = a11 * b11 + a12 * b21; // + a13 * b31; // zero + result.data[1] = a21 * b11 + a22 * b21; // + a23 * b31; // zero - result.data[0] = a11 * b11 + a12 * b21;// + a13 * b31; // zero - result.data[1] = a21 * b11 + a22 * b21;// + a23 * b31; // zero - - result.data[2] = a11 * b12 + a12 * b22;// + a13 * b32; // zero - result.data[3] = a21 * b12 + a22 * b22;// + a23 * b32; // zero + result.data[2] = a11 * b12 + a12 * b22; // + a13 * b32; // zero + result.data[3] = a21 * b12 + a22 * b22; // + a23 * b32; // zero - result.data[4] = a11 * b13 + a12 * b23 + a13;// * b33; // one - result.data[5] = a21 * b13 + a22 * b23 + a23;// * b33; // one + result.data[4] = a11 * b13 + a12 * b23 + a13; // * b33; // one + result.data[5] = a21 * b13 + a22 * b23 + a23; // * b33; // one const s = this.getScale(); result._scaleSignX = sign(s.x) * sign(result._scaleSignX); @@ -382,14 +380,7 @@ export class AffineMatrix { } public isIdentity(): boolean { - return ( - this.data[0] === 1 && - this.data[1] === 0 && - this.data[2] === 0 && - this.data[3] === 1 && - this.data[4] === 0 && - this.data[5] === 0 - ); + return this.data[0] === 1 && this.data[1] === 0 && this.data[2] === 0 && this.data[3] === 1 && this.data[4] === 0 && this.data[5] === 0; } /** @@ -425,5 +416,4 @@ export class AffineMatrix { [0 0 1] `; } - -} \ No newline at end of file +} diff --git a/src/engine/Math/coord-plane.ts b/src/engine/Math/coord-plane.ts index c458f4be..c2dfe25c 100644 --- a/src/engine/Math/coord-plane.ts +++ b/src/engine/Math/coord-plane.ts @@ -12,4 +12,4 @@ export enum CoordPlane { * to screen coordinates ignoring the camera. */ Screen = 'screen' -} \ No newline at end of file +} diff --git a/src/engine/Math/global-coordinates.ts b/src/engine/Math/global-coordinates.ts index a3e596c0..865d61b5 100644 --- a/src/engine/Math/global-coordinates.ts +++ b/src/engine/Math/global-coordinates.ts @@ -28,5 +28,9 @@ export class GlobalCoordinates { return new GlobalCoordinates(worldPos, pagePos, screenPos); } - constructor(public worldPos: Vector, public pagePos: Vector, public screenPos: Vector) {} + constructor( + public worldPos: Vector, + public pagePos: Vector, + public screenPos: Vector + ) {} } diff --git a/src/engine/Math/line-segment.ts b/src/engine/Math/line-segment.ts index e5554081..cee0c828 100644 --- a/src/engine/Math/line-segment.ts +++ b/src/engine/Math/line-segment.ts @@ -5,12 +5,14 @@ import { Vector } from './vector'; */ export class LineSegment { - /** * @param begin The starting point of the line segment * @param end The ending point of the line segment */ - constructor(public readonly begin: Vector, public readonly end: Vector) {} + constructor( + public readonly begin: Vector, + public readonly end: Vector + ) {} /** * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines. @@ -34,7 +36,7 @@ export class LineSegment { if (this._normal) { return this._normal; } - return this._normal = this.end.sub(this.begin).normal(); + return (this._normal = this.end.sub(this.begin).normal()); } private _dir: Vector; @@ -42,7 +44,7 @@ export class LineSegment { if (this._dir) { return this._dir; } - return this._dir = this.end.sub(this.begin); + return (this._dir = this.end.sub(this.begin)); } public getPoints(): Vector[] { @@ -60,7 +62,7 @@ export class LineSegment { const begin = this.begin; const end = this.end; const distance = begin.distance(end); - return this._slope = end.sub(begin).scale(1 / distance); + return (this._slope = end.sub(begin).scale(1 / distance)); } /** @@ -83,7 +85,7 @@ export class LineSegment { const begin = this.begin; const end = this.end; const distance = begin.distance(end); - return this._length = distance; + return (this._length = distance); } /** diff --git a/src/engine/Math/matrix.ts b/src/engine/Math/matrix.ts index f845f951..4582c0c6 100644 --- a/src/engine/Math/matrix.ts +++ b/src/engine/Math/matrix.ts @@ -98,7 +98,7 @@ export class Matrix { } public static fromFloat32Array(data: Float32Array) { - const matrix = new Matrix(); + const matrix = new Matrix(); matrix.data = data; return matrix; } @@ -291,7 +291,6 @@ export class Matrix { } } - /** * Applies translation to the current matrix mutating it * @param x diff --git a/src/engine/Math/projection.ts b/src/engine/Math/projection.ts index 07e4b9e8..196e9d6f 100644 --- a/src/engine/Math/projection.ts +++ b/src/engine/Math/projection.ts @@ -3,7 +3,10 @@ */ export class Projection { - constructor(public min: number, public max: number) {} + constructor( + public min: number, + public max: number + ) {} public overlaps(projection: Projection): boolean { return this.max > projection.min && projection.max > this.min; } diff --git a/src/engine/Math/transform.ts b/src/engine/Math/transform.ts index 2413613c..5074392e 100644 --- a/src/engine/Math/transform.ts +++ b/src/engine/Math/transform.ts @@ -139,8 +139,8 @@ export class Transform { get globalScale() { return new VectorView({ - getX: () => this.parent ? this.matrix.getScaleX() : this.scale.x, - getY: () => this.parent ? this.matrix.getScaleY() : this.scale.y, + getX: () => (this.parent ? this.matrix.getScaleX() : this.scale.x), + getY: () => (this.parent ? this.matrix.getScaleY() : this.scale.y), setX: (x) => { if (this.parent) { const globalScaleX = this.parent.globalScale.x; @@ -186,18 +186,14 @@ export class Transform { } private _calculateMatrix(): AffineMatrix { - const matrix = AffineMatrix.identity() - .translate(this.pos.x, this.pos.y) - .rotate(this.rotation) - .scale(this.scale.x, this.scale.y); + const matrix = AffineMatrix.identity().translate(this.pos.x, this.pos.y).rotate(this.rotation).scale(this.scale.x, this.scale.y); return matrix; } - public flagDirty() { this._isDirty = true; this._isInverseDirty = true; - for (let i = 0; i < this._children.length; i ++) { + for (let i = 0; i < this._children.length; i++) { this._children[i].flagDirty(); } } @@ -232,4 +228,4 @@ export class Transform { target.flagDirty(); return target; } -} \ No newline at end of file +} diff --git a/src/engine/Math/util.ts b/src/engine/Math/util.ts index e056c6b8..4572fc59 100644 --- a/src/engine/Math/util.ts +++ b/src/engine/Math/util.ts @@ -25,7 +25,7 @@ export function sign(val: number): number { return 0; } return val < 0 ? -1 : 1; -}; +} /** * Clamps a value between a min and max inclusive @@ -34,7 +34,6 @@ export function clamp(val: number, min: number, max: number) { return Math.min(Math.max(min, val), max); } - /** * Convert an angle to be the equivalent in the range [0, 2PI] */ @@ -88,4 +87,4 @@ export function randomInRange(min: number, max: number, random: Random = new Ran */ export function randomIntInRange(min: number, max: number, random: Random = new Random()): number { return random ? random.integer(min, max) : Math.round(randomInRange(min, max)); -} \ No newline at end of file +} diff --git a/src/engine/Math/vector.ts b/src/engine/Math/vector.ts index 4d4b639e..72a624d6 100644 --- a/src/engine/Math/vector.ts +++ b/src/engine/Math/vector.ts @@ -9,7 +9,7 @@ export class Vector implements Clonable { /** * Get or set the vector equals epsilon, by default 0.001 meaning vectors within that tolerance on x or y will be considered equal. */ - public static EQUALS_EPSILON = .001; + public static EQUALS_EPSILON = 0.001; /** * A (0, 0) vector */ diff --git a/src/engine/Math/watch-vector.ts b/src/engine/Math/watch-vector.ts index e1fbb741..fab02142 100644 --- a/src/engine/Math/watch-vector.ts +++ b/src/engine/Math/watch-vector.ts @@ -4,11 +4,14 @@ import { Vector } from './vector'; * Wraps a vector and watches for changes in the x/y, modifies the original vector. */ export class WatchVector extends Vector { - constructor(public original: Vector, public change: (x: number, y: number) => any) { + constructor( + public original: Vector, + public change: (x: number, y: number) => any + ) { super(original.x, original.y); } public get x() { - return this._x = this.original.x; + return (this._x = this.original.x); } public set x(newX: number) { @@ -17,11 +20,11 @@ export class WatchVector extends Vector { } public get y() { - return this._y = this.original.y; + return (this._y = this.original.y); } public set y(newY: number) { this.change(this._x, newY); this._y = this.original.y = newY; } -} \ No newline at end of file +} diff --git a/src/engine/Particles.ts b/src/engine/Particles.ts index 75c9d4c5..ec1e09f9 100644 --- a/src/engine/Particles.ts +++ b/src/engine/Particles.ts @@ -112,7 +112,7 @@ export class ParticleImpl extends Entity { this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation); } else { this.velocity = velocity || this.velocity; - this.position = (position || this.position); + this.position = position || this.position; } this.acceleration = acceleration || this.acceleration; this._rRate = (this.endColor.r - this.beginColor.r) / this.life; diff --git a/src/engine/Resources/Font.ts b/src/engine/Resources/Font.ts index 88ef41c4..d2dec1b0 100644 --- a/src/engine/Resources/Font.ts +++ b/src/engine/Resources/Font.ts @@ -4,15 +4,11 @@ import { GraphicOptions, RasterOptions } from '../Graphics'; import { Loadable } from '../Interfaces/Loadable'; import { Resource } from './Resource'; - -export interface FontSourceOptions - extends Omit, - GraphicOptions, - RasterOptions { +export interface FontSourceOptions extends Omit, GraphicOptions, RasterOptions { /** * Whether or not to cache-bust requests */ - bustCache?: boolean + bustCache?: boolean; } export class FontSource implements Loadable { @@ -22,7 +18,6 @@ export class FontSource implements Loadable { data!: FontFace; - constructor( /** * Path to the font resource relative from the HTML document hosting the game, or absolute @@ -55,9 +50,7 @@ export class FontSource implements Loadable { await this.data.load(); this._isLoaded = true; } catch (error) { - throw `Error loading FontSource from path '${this.path}' with error [${ - (error as Error).message - }]`; + throw `Error loading FontSource from path '${this.path}' with error [${(error as Error).message}]`; } return this.data; } diff --git a/src/engine/Resources/Gif.ts b/src/engine/Resources/Gif.ts index e7ea3798..50cbb645 100644 --- a/src/engine/Resources/Gif.ts +++ b/src/engine/Resources/Gif.ts @@ -24,7 +24,6 @@ export class Gif implements Loadable { */ public height: number; - private _stream: Stream = null; private _gif: ParseGif = null; private _textures: ImageSource[] = []; @@ -38,7 +37,11 @@ export class Gif implements Loadable { * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]] * @param bustCache Optionally load texture with cache busting */ - constructor(public path: string, public color: Color = Color.Magenta, bustCache = false) { + constructor( + public path: string, + public color: Color = Color.Magenta, + bustCache = false + ) { this._resource = new Resource(path, 'arraybuffer', bustCache); this._transparentColor = color; } @@ -62,11 +65,11 @@ export class Gif implements Loadable { const arraybuffer = await this._resource.load(); this._stream = new Stream(arraybuffer); this._gif = new ParseGif(this._stream, this._transparentColor); - const images = this._gif.images.map(i => new ImageSource(i.src, false)); + const images = this._gif.images.map((i) => new ImageSource(i.src, false)); // Load all textures - await Promise.all(images.map(t => t.load())); - return this.data = this._textures = images; + await Promise.all(images.map((t) => t.load())); + return (this.data = this._textures = images); } public isLoaded() { diff --git a/src/engine/Resources/Index.ts b/src/engine/Resources/Index.ts index 3f91af5b..a540a6d5 100644 --- a/src/engine/Resources/Index.ts +++ b/src/engine/Resources/Index.ts @@ -1,4 +1,4 @@ export * from './Resource'; export * from './Sound/Index'; export * from './Gif'; -export * from './Font'; \ No newline at end of file +export * from './Font'; diff --git a/src/engine/Resources/Resource.ts b/src/engine/Resources/Resource.ts index 99ac9371..12dda892 100644 --- a/src/engine/Resources/Resource.ts +++ b/src/engine/Resources/Resource.ts @@ -3,12 +3,12 @@ import { Logger } from '../Util/Log'; import { EventEmitter } from '../EventEmitter'; export type ResourceEvents = { - complete: any, - load: ProgressEvent, - loadstart: ProgressEvent, - progress: ProgressEvent, - error: ProgressEvent -} + complete: any; + load: ProgressEvent; + loadstart: ProgressEvent; + progress: ProgressEvent; + error: ProgressEvent; +}; export const ResourceEvents = { Complete: 'complete', @@ -46,7 +46,6 @@ export class Resource implements Loadable { return this.data !== null; } - private _cacheBust(uri: string): string { const query: RegExp = /\?\w*=\w*/; if (query.test(uri)) { diff --git a/src/engine/Resources/Sound/Sound.ts b/src/engine/Resources/Sound/Sound.ts index a59b6cf7..55d5aba9 100644 --- a/src/engine/Resources/Sound/Sound.ts +++ b/src/engine/Resources/Sound/Sound.ts @@ -11,14 +11,14 @@ import { Logger } from '../../Util/Log'; import { EventEmitter, EventKey, Handler, Subscription } from '../../EventEmitter'; export type SoundEvents = { - volumechange: NativeSoundEvent, - processed: NativeSoundProcessedEvent, - pause: NativeSoundEvent, - stop: NativeSoundEvent, - playbackend: NativeSoundEvent, - resume: NativeSoundEvent, - playbackstart: NativeSoundEvent -} + volumechange: NativeSoundEvent; + processed: NativeSoundProcessedEvent; + pause: NativeSoundEvent; + stop: NativeSoundEvent; + playbackend: NativeSoundEvent; + resume: NativeSoundEvent; + playbackstart: NativeSoundEvent; +}; export const SoundEvents = { VolumeChange: 'volumechange', @@ -86,7 +86,7 @@ export class Sound implements Audio, Loadable { * * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds. */ - public set duration(duration: number | undefined){ + public set duration(duration: number | undefined) { this._duration = duration; } @@ -105,7 +105,6 @@ export class Sound implements Audio, Loadable { this._resource.path = val; } - /** * Should excalibur add a cache busting querystring? By default false. * Must be set before loading @@ -165,7 +164,7 @@ export class Sound implements Audio, Loadable { const audiobuffer = await this.decodeAudio(arraybuffer.slice(0)); this._duration = this._duration ?? audiobuffer?.duration ?? undefined; this.events.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer)); - return this.data = audiobuffer; + return (this.data = audiobuffer); } public async decodeAudio(data: ArrayBuffer): Promise { @@ -226,11 +225,11 @@ export class Sound implements Audio, Loadable { } public isPaused(): boolean { - return this._tracks.some(t => t.isPaused()); + return this._tracks.some((t) => t.isPaused()); } public isStopped(): boolean { - return this._tracks.some(t => t.isStopped()); + return this._tracks.some((t) => t.isStopped()); } /** @@ -295,7 +294,7 @@ export class Sound implements Audio, Loadable { public set playbackRate(playbackRate: number) { this._playbackRate = playbackRate; - this._tracks.forEach(t => { + this._tracks.forEach((t) => { t.playbackRate = this._playbackRate; }); } @@ -310,8 +309,10 @@ export class Sound implements Audio, Loadable { public getTotalPlaybackDuration() { if (!this.isLoaded()) { - this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.` + - `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`); + this.logger.warnOnce( + `Sound from ${this.path} is not loaded, cannot return total playback duration.` + + `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/` + ); return 0; } return this.data.duration; @@ -330,8 +331,6 @@ export class Sound implements Audio, Loadable { return 0; } - - /** * Get Id of provided AudioInstance in current trackList * @param track [[Audio]] which Id is to be given @@ -345,10 +344,12 @@ export class Sound implements Audio, Loadable { const resumed: Promise[] = []; // ensure we resume *current* tracks (if paused) for (const track of this._tracks) { - resumed.push(track.play().then(() => { - this._tracks.splice(this.getTrackId(track), 1); - return true; - })); + resumed.push( + track.play().then(() => { + this._tracks.splice(this.getTrackId(track), 1); + return true; + }) + ); } this.events.emit('resume', new NativeSoundEvent(this)); diff --git a/src/engine/Resources/Sound/WebAudioInstance.ts b/src/engine/Resources/Sound/WebAudioInstance.ts index 4d105d87..b294cc42 100644 --- a/src/engine/Resources/Sound/WebAudioInstance.ts +++ b/src/engine/Resources/Sound/WebAudioInstance.ts @@ -19,67 +19,69 @@ export class WebAudioInstance implements Audio { private _volumeNode = this._audioContext.createGain(); private _playingFuture = new Future(); - private _stateMachine = StateMachine.create({ - start: 'STOPPED', - states: { - PLAYING: { - onEnter: ({data}: {from: string, data: SoundState}) => { - - // Buffer nodes are single use - this._createNewBufferSource(); - this._handleEnd(); - if (this.loop) { - // when looping don't set a duration - this._instance.start(0, data.pausedAt * this._playbackRate); - } else { - this._instance.start(0, data.pausedAt * this._playbackRate, this.duration); - } - data.startedAt = (this._audioContext.currentTime - data.pausedAt); - data.pausedAt = 0; + private _stateMachine = StateMachine.create( + { + start: 'STOPPED', + states: { + PLAYING: { + onEnter: ({ data }: { from: string; data: SoundState }) => { + // Buffer nodes are single use + this._createNewBufferSource(); + this._handleEnd(); + if (this.loop) { + // when looping don't set a duration + this._instance.start(0, data.pausedAt * this._playbackRate); + } else { + this._instance.start(0, data.pausedAt * this._playbackRate, this.duration); + } + data.startedAt = this._audioContext.currentTime - data.pausedAt; + data.pausedAt = 0; + }, + onState: () => this._playStarted(), + onExit: ({ to }) => { + // If you've exited early only resolve if explicitly STOPPED + if (to === 'STOPPED') { + this._playingFuture.resolve(true); + } + // Whenever you're not playing... you stop! + this._instance.onended = null; // disconnect the wired on-end handler + this._instance.disconnect(); + this._instance.stop(0); + this._instance = null; + }, + transitions: ['STOPPED', 'PAUSED', 'SEEK'] }, - onState: () => this._playStarted(), - onExit: ({to}) => { - // If you've exited early only resolve if explicitly STOPPED - if (to === 'STOPPED') { - this._playingFuture.resolve(true); - } - // Whenever you're not playing... you stop! - this._instance.onended = null; // disconnect the wired on-end handler - this._instance.disconnect(); - this._instance.stop(0); - this._instance = null; - }, - transitions: ['STOPPED', 'PAUSED', 'SEEK'] - }, - SEEK: { - onEnter: ({ eventData: position, data }: {eventData?: number, data: SoundState}) => { - data.pausedAt = (position ?? 0) / this._playbackRate; - data.startedAt = 0; - }, - transitions: ['*'] - }, - STOPPED: { - onEnter: ({data}: {from: string, data: SoundState}) => { - data.pausedAt = 0; - data.startedAt = 0; - this._playingFuture.resolve(true); + SEEK: { + onEnter: ({ eventData: position, data }: { eventData?: number; data: SoundState }) => { + data.pausedAt = (position ?? 0) / this._playbackRate; + data.startedAt = 0; + }, + transitions: ['*'] }, - transitions: ['PLAYING', 'PAUSED', 'SEEK'] - }, - PAUSED: { - onEnter: ({data}: {data: SoundState}) => { - // Playback rate will be a scale factor of how fast/slow the audio is being played - // default is 1.0 - // we need to invert it to get the time scale - data.pausedAt = (this._audioContext.currentTime - data.startedAt); + STOPPED: { + onEnter: ({ data }: { from: string; data: SoundState }) => { + data.pausedAt = 0; + data.startedAt = 0; + this._playingFuture.resolve(true); + }, + transitions: ['PLAYING', 'PAUSED', 'SEEK'] }, - transitions: ['PLAYING', 'STOPPED', 'SEEK'] + PAUSED: { + onEnter: ({ data }: { data: SoundState }) => { + // Playback rate will be a scale factor of how fast/slow the audio is being played + // default is 1.0 + // we need to invert it to get the time scale + data.pausedAt = this._audioContext.currentTime - data.startedAt; + }, + transitions: ['PLAYING', 'STOPPED', 'SEEK'] + } } - } - }, { - startedAt: 0, - pausedAt: 0 - } as SoundState); + }, + { + startedAt: 0, + pausedAt: 0 + } as SoundState + ); private _createNewBufferSource() { this._instance = this._audioContext.createBufferSource(); @@ -196,7 +198,7 @@ export class WebAudioInstance implements Audio { } public getPlaybackPosition() { - const {pausedAt, startedAt} = this._stateMachine.data; + const { pausedAt, startedAt } = this._stateMachine.data; if (pausedAt) { return pausedAt * this._playbackRate; } diff --git a/src/engine/Scene.ts b/src/engine/Scene.ts index 8d34db15..e6b2cecf 100644 --- a/src/engine/Scene.ts +++ b/src/engine/Scene.ts @@ -45,17 +45,17 @@ export class PreLoadEvent { } export type SceneEvents = { - initialize: InitializeEvent, - activate: ActivateEvent, - deactivate: DeactivateEvent, - preupdate: PreUpdateEvent, - postupdate: PostUpdateEvent, - predraw: PreDrawEvent, - postdraw: PostDrawEvent, - predebugdraw: PreDebugDrawEvent, - postdebugdraw: PostDebugDrawEvent - preload: PreLoadEvent -} + initialize: InitializeEvent; + activate: ActivateEvent; + deactivate: DeactivateEvent; + preupdate: PreUpdateEvent; + postupdate: PostUpdateEvent; + predraw: PreDrawEvent; + postdraw: PostDrawEvent; + predebugdraw: PreDebugDrawEvent; + postdebugdraw: PostDebugDrawEvent; + preload: PreLoadEvent; +}; export const SceneEvents = { Initialize: 'initialize', @@ -85,8 +85,7 @@ export function isSceneConstructor(x: any): x is SceneConstructor { * * Typical usages of a scene include: levels, menus, loading screens, etc. */ -export class Scene -implements CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw { +export class Scene implements CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw { private _logger: Logger = Logger.getInstance(); public events = new EventEmitter(); @@ -309,7 +308,6 @@ implements CanInitialize, CanActivate, CanDeactivate, CanUpdate return this._isInitialized; } - /** * It is not recommended that internal excalibur methods be overridden, do so at your own risk. * @@ -544,8 +542,6 @@ implements CanInitialize, CanActivate, CanDeactivate, CanUpdate } } - - /** * Removes a [[Timer]] from it's current scene * and adds it to this scene. diff --git a/src/engine/Screen.ts b/src/engine/Screen.ts index f31918ef..25631648 100644 --- a/src/engine/Screen.ts +++ b/src/engine/Screen.ts @@ -239,15 +239,15 @@ export type ScreenEvents = { /** * Fires when the screen resizes, useful if you have logic that needs to be aware of resolution/viewport constraints */ - 'resize': ScreenResizeEvent; + resize: ScreenResizeEvent; /** * Fires when the pixel ratio changes, useful to know if you've moved to a hidpi screen or back */ - 'pixelratio': PixelRatioChangeEvent; + pixelratio: PixelRatioChangeEvent; /** * Fires when the browser fullscreen api is successfully engaged or disengaged */ - 'fullscreen': FullScreenChangeEvent; + fullscreen: FullScreenChangeEvent; }; export const ScreenEvents = { @@ -501,8 +501,6 @@ export class Screen { } } - - public applyResolutionAndViewport() { if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) { const scaledResolutionSupported = this.graphicsContext.checkIfResolutionSupported({ @@ -512,16 +510,17 @@ export class Screen { if (!scaledResolutionSupported) { this._logger.warnOnce( `The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` + - ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' + - ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' + - ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).'); + ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' + + ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' + + ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' + ); // Attempt to recover if the user hasn't configured a specific ratio for up scaling if (!this.pixelRatioOverride) { - let currentPixelRatio = Math.max(1, this.pixelRatio - .5); + let currentPixelRatio = Math.max(1, this.pixelRatio - 0.5); let newResolutionSupported = false; while (currentPixelRatio > 1 && !newResolutionSupported) { - currentPixelRatio = Math.max(1, currentPixelRatio - .5); + currentPixelRatio = Math.max(1, currentPixelRatio - 0.5); const width = this._resolution.width * currentPixelRatio; const height = this._resolution.height * currentPixelRatio; newResolutionSupported = this.graphicsContext.checkIfResolutionSupported({ width, height }); @@ -529,9 +528,10 @@ export class Screen { this.pixelRatioOverride = currentPixelRatio; this._logger.warnOnce( 'Scaled resolution too big attempted recovery!' + - ` Pixel ratio was automatically reduced to (${this.pixelRatio}) to avoid 4k texture limit.` + - ' Setting `ex.Engine({pixelRatio: ...}) will override any automatic recalculation, do so at your own risk.` ' + - ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).'); + ` Pixel ratio was automatically reduced to (${this.pixelRatio}) to avoid 4k texture limit.` + + ' Setting `ex.Engine({pixelRatio: ...}) will override any automatic recalculation, do so at your own risk.` ' + + ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' + ); } } } @@ -752,11 +752,8 @@ export class Screen { * World bounds are in world coordinates, useful for culling objects offscreen that are in world space */ public getWorldBounds(): BoundingBox { - const bounds = BoundingBox.fromDimension( - this.resolution.width, - this.resolution.height, - Vector.Half) - .scale(vec(1/this._camera.zoom, 1/this._camera.zoom)) + const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Half) + .scale(vec(1 / this._camera.zoom, 1 / this._camera.zoom)) .rotate(this._camera.rotation) .translate(this._camera.drawPos); return bounds; @@ -768,10 +765,7 @@ export class Screen { * Screen bounds are in screen coordinates, useful for culling objects offscreen that are in screen space */ public getScreenBounds(): BoundingBox { - const bounds = BoundingBox.fromDimension( - this.resolution.width, - this.resolution.height, - Vector.Zero, Vector.Zero); + const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero, Vector.Zero); return bounds; } @@ -901,20 +895,16 @@ export class Screen { } satisfies ScreenResizeEvent); } - - private _computeFitContainerAndFill() { this.canvas.style.width = '100%'; this.canvas.style.height = '100%'; - this._computeFitAndFill( - this.canvas.offsetWidth, - this.canvas.offsetHeight, { - width: 100, - widthUnit: 'percent', - height: 100, - heightUnit: 'percent' - }); + this._computeFitAndFill(this.canvas.offsetWidth, this.canvas.offsetHeight, { + width: 100, + widthUnit: 'percent', + height: 100, + heightUnit: 'percent' + }); this.events.emit('resize', { resolution: this.resolution, viewport: this.viewport @@ -930,8 +920,8 @@ export class Screen { if (vw / vh <= this._contentResolution.width / this._contentResolution.height) { // compute new resolution to match the original aspect ratio this.resolution = { - width: vw * this._contentResolution.width / vw, - height: vw * this._contentResolution.width / vw * vh / vw + width: (vw * this._contentResolution.width) / vw, + height: (((vw * this._contentResolution.width) / vw) * vh) / vw }; const clip = (this.resolution.height - this._contentResolution.height) / 2; this._contentArea = new BoundingBox({ @@ -948,8 +938,8 @@ export class Screen { }); } else { this.resolution = { - width: vh * this._contentResolution.height / vh * vw / vh, - height: vh * this._contentResolution.height / vh + width: (((vh * this._contentResolution.height) / vh) * vw) / vh, + height: (vh * this._contentResolution.height) / vh }; const clip = (this.resolution.width - this._contentResolution.width) / 2; this._contentArea = new BoundingBox({ @@ -1038,7 +1028,7 @@ export class Screen { const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero); // return safe area if (this.viewport.width > vw) { - const clip = (this.viewport.width - vw)/this.viewport.width * this.resolution.width; + const clip = ((this.viewport.width - vw) / this.viewport.width) * this.resolution.width; bounds.top = 0; bounds.left = clip / 2; bounds.right = this.resolution.width - clip / 2; @@ -1046,7 +1036,7 @@ export class Screen { } if (this.viewport.height > vh) { - const clip = (this.viewport.height - vh)/this.viewport.height * this.resolution.height; + const clip = ((this.viewport.height - vh) / this.viewport.height) * this.resolution.height; bounds.top = clip / 2; bounds.left = 0; bounds.bottom = this.resolution.height - clip / 2; @@ -1125,8 +1115,8 @@ export class Screen { document.body.style.margin = '0px'; document.body.style.overflow = 'hidden'; this.resolution = { - width: ( parent).innerWidth, - height: ( parent).innerHeight + width: (parent).innerWidth, + height: (parent).innerHeight }; this.viewport = this.resolution; @@ -1146,7 +1136,7 @@ export class Screen { this._computeFitScreenAndFill(); } - if (this.displayMode === DisplayMode.FitContainerAndFill){ + if (this.displayMode === DisplayMode.FitContainerAndFill) { this._computeFitContainerAndFill(); } @@ -1154,7 +1144,7 @@ export class Screen { this._computeFitScreenAndZoom(); } - if (this.displayMode === DisplayMode.FitContainerAndZoom){ + if (this.displayMode === DisplayMode.FitContainerAndZoom) { this._computeFitContainerAndZoom(); } } diff --git a/src/engine/ScreenElement.ts b/src/engine/ScreenElement.ts index 0f3fd145..174c210e 100644 --- a/src/engine/ScreenElement.ts +++ b/src/engine/ScreenElement.ts @@ -29,9 +29,7 @@ export class ScreenElement extends Actor { this.body.collisionType = config?.collisionType ?? CollisionType.PreventCollision; this.pointer.useGraphicsBounds = true; this.pointer.useColliderShape = false; - if (!config?.collider && - config?.width > 0 && - config?.height > 0) { + if (!config?.collider && config?.width > 0 && config?.height > 0) { this.collider.useBoxCollider(this.width, this.height, this.anchor); } } diff --git a/src/engine/TileMap/IsometricEntityComponent.ts b/src/engine/TileMap/IsometricEntityComponent.ts index 5ce11866..ef96a990 100644 --- a/src/engine/TileMap/IsometricEntityComponent.ts +++ b/src/engine/TileMap/IsometricEntityComponent.ts @@ -30,4 +30,4 @@ export class IsometricEntityComponent extends Component { this.tileWidth = mapOrOptions.tileWidth; this.tileHeight = mapOrOptions.tileHeight; } -} \ No newline at end of file +} diff --git a/src/engine/TileMap/IsometricEntitySystem.ts b/src/engine/TileMap/IsometricEntitySystem.ts index 95368263..40ab2ec6 100644 --- a/src/engine/TileMap/IsometricEntitySystem.ts +++ b/src/engine/TileMap/IsometricEntitySystem.ts @@ -3,7 +3,6 @@ import { TransformComponent } from '../EntityComponentSystem/Components/Transfor import { IsometricEntityComponent } from './IsometricEntityComponent'; import { Query, SystemPriority, World } from '../EntityComponentSystem'; - export class IsometricEntitySystem extends System { public readonly systemType = SystemType.Update; priority: number = SystemPriority.Lower; @@ -26,4 +25,4 @@ export class IsometricEntitySystem extends System { transform.z = newZ; } } -} \ No newline at end of file +} diff --git a/src/engine/TileMap/IsometricMap.ts b/src/engine/TileMap/IsometricMap.ts index 15c4bcdc..199a0a06 100644 --- a/src/engine/TileMap/IsometricMap.ts +++ b/src/engine/TileMap/IsometricMap.ts @@ -1,5 +1,5 @@ import { BodyComponent } from '../Collision/BodyComponent'; -import { BoundingBox} from '../Collision/BoundingBox'; +import { BoundingBox } from '../Collision/BoundingBox'; import { ColliderComponent } from '../Collision/ColliderComponent'; import { Collider } from '../Collision/Colliders/Collider'; import { CollisionType } from '../Collision/CollisionType'; @@ -19,7 +19,7 @@ export type IsometricTilePointerEvents = { pointerdown: PointerEvent; pointermove: PointerEvent; pointercancel: PointerEvent; -} +}; export class IsometricTile extends Entity { /** @@ -38,7 +38,7 @@ export class IsometricTile extends Entity { /** * Tile graphics */ - public addGraphic(graphic: Graphic, options?: {offset?: Vector}) { + public addGraphic(graphic: Graphic, options?: { offset?: Vector }) { this._graphics.push(graphic); this._gfx.visible = this.map.visible; this._gfx.opacity = this.map.opacity; @@ -54,7 +54,8 @@ export class IsometricTile extends Entity { for (const graphic of this._graphics) { const offset = vec( this.map.graphicsOffset.x - this.map.tileWidth / 2, - this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight))); + this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight) + ); bounds = bounds.combine(graphic.localBounds.translate(offset)); } return bounds; @@ -186,7 +187,7 @@ export class IsometricTile extends Entity { const totalHeight = this.map.tileHeight; // initial guess at gfx bounds based on the tile - const offset = vec(0, (this.map.renderFromTopOfGraphic ? totalHeight : 0)); + const offset = vec(0, this.map.renderFromTopOfGraphic ? totalHeight : 0); this._gfx.localBounds = this._tileBounds = new BoundingBox({ left: -totalWidth / 2, top: -totalHeight, @@ -204,7 +205,8 @@ export class IsometricTile extends Entity { graphic.draw( gfx, this.map.graphicsOffset.x, - this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight))); + this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight) + ); } gfx.restore(); } @@ -313,15 +315,18 @@ export class IsometricMap extends Entity { private _composite: CompositeCollider; constructor(options: IsometricMapOptions) { - super([ - new TransformComponent(), - new BodyComponent({ - type: CollisionType.Fixed - }), - new ColliderComponent(), - new PointerComponent(), - new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false) - ], options.name); + super( + [ + new TransformComponent(), + new BodyComponent({ + type: CollisionType.Fixed + }), + new ColliderComponent(), + new PointerComponent(), + new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false) + ], + options.name + ); const { pos, tileWidth, tileHeight, columns: width, rows: height, renderFromTopOfGraphic, graphicsOffset, elevation } = options; this.transform = this.get(TransformComponent); @@ -331,7 +336,7 @@ export class IsometricMap extends Entity { this.collider = this.get(ColliderComponent); if (this.collider) { - this.collider.set(this._composite = new CompositeCollider([])); + this.collider.set((this._composite = new CompositeCollider([]))); } this.pointer = this.get(PointerComponent); @@ -359,7 +364,7 @@ export class IsometricMap extends Entity { this.pointer.localBounds = BoundingBox.fromDimension( tileWidth * width * this.transform.scale.x, tileHeight * height * this.transform.scale.y, - vec(.5, 0) + vec(0.5, 0) ); this._setupPointerToTile(); @@ -432,8 +437,9 @@ export class IsometricMap extends Entity { const halfTileHeight = this.tileHeight / 2; // See https://clintbellanger.net/articles/isometric_math/ for formula return vec( - ~~((worldCoordinate.x / halfTileWidth + (worldCoordinate.y / halfTileHeight)) / 2), - ~~((worldCoordinate.y / halfTileHeight - (worldCoordinate.x / halfTileWidth)) / 2)); + ~~((worldCoordinate.x / halfTileWidth + worldCoordinate.y / halfTileHeight) / 2), + ~~((worldCoordinate.y / halfTileHeight - worldCoordinate.x / halfTileWidth) / 2) + ); } /** @@ -475,7 +481,7 @@ export class IsometricMap extends Entity { for (const tile of this.tiles) { const currentZ = tile.get(TransformComponent).z; if (currentZ > maxZ) { - maxZ = currentZ; + maxZ = currentZ; } } return maxZ; @@ -486,22 +492,10 @@ export class IsometricMap extends Entity { * @param gfx */ public debug(gfx: ExcaliburGraphicsContext, debugFlags: DebugConfig) { - const { - showAll, - showPosition, - positionColor, - positionSize, - showGrid, - gridColor, - gridWidth, - showColliderGeometry - } = debugFlags.isometric; - - const { - geometryColor, - geometryLineWidth, - geometryPointSize - } = debugFlags.collider; + const { showAll, showPosition, positionColor, positionSize, showGrid, gridColor, gridWidth, showColliderGeometry } = + debugFlags.isometric; + + const { geometryColor, geometryLineWidth, geometryPointSize } = debugFlags.collider; gfx.save(); gfx.z = this._getMaxZIndex() + 0.5; if (showAll || showGrid) { @@ -525,7 +519,8 @@ export class IsometricMap extends Entity { } if (showAll || showColliderGeometry) { for (const tile of this.tiles) { - if (tile.solid) { // only draw solid tiles + if (tile.solid) { + // only draw solid tiles for (const collider of tile.getColliders()) { collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize }); } @@ -534,4 +529,4 @@ export class IsometricMap extends Entity { } gfx.restore(); } -} \ No newline at end of file +} diff --git a/src/engine/TileMap/TileMap.ts b/src/engine/TileMap/TileMap.ts index a06e3eaa..882b9784 100644 --- a/src/engine/TileMap/TileMap.ts +++ b/src/engine/TileMap/TileMap.ts @@ -68,14 +68,15 @@ export type TilePointerEvents = { pointerdown: PointerEvent; pointermove: PointerEvent; pointercancel: PointerEvent; -} +}; -export type TileMapEvents = EntityEvents & TilePointerEvents & { - preupdate: PreUpdateEvent; - postupdate: PostUpdateEvent; - predraw: PreDrawEvent; - postdraw: PostDrawEvent; -} +export type TileMapEvents = EntityEvents & + TilePointerEvents & { + preupdate: PreUpdateEvent; + postupdate: PostUpdateEvent; + predraw: PreDrawEvent; + postdraw: PostDrawEvent; + }; export const TileMapEvents = { PreUpdate: 'preupdate', @@ -225,7 +226,6 @@ export class TileMap extends Entity { this.events.off(eventName, handler); } - /** * @param options */ @@ -246,7 +246,7 @@ export class TileMap extends Entity { ); this.addComponent(new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false)); this.addComponent(new ColliderComponent()); - this.addComponent(new PointerComponent); + this.addComponent(new PointerComponent()); this.pointer = this.get(PointerComponent); this._graphics = this.get(GraphicsComponent); this.transform = this.get(TransformComponent); @@ -326,7 +326,6 @@ export class TileMap extends Entity { } } - /** * Tiles colliders based on the solid tiles in the tilemap. */ @@ -346,10 +345,12 @@ export class TileMap extends Entity { const shareEdges = (prev: BoundingBox, next: BoundingBox) => { if (prev && next) { // same top/bottom - return prev.top === next.top && - prev.bottom === next.bottom && - // Shared right/left edge - prev.right === next.left; + return ( + prev.top === next.top && + prev.bottom === next.bottom && + // Shared right/left edge + prev.right === next.left + ); } return false; }; @@ -464,7 +465,7 @@ export class TileMap extends Entity { * returns `null` if no Tile was found. */ public getTileByPoint(point: Vector): Tile | null { - const {x, y} = this._getTileCoordinates(point); + const { x, y } = this._getTileCoordinates(point); const tile = this.getTile(x, y); if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) { return tile; @@ -472,13 +473,13 @@ export class TileMap extends Entity { return null; } - private _getTileCoordinates(point: Vector): {x: number, y: number} { + private _getTileCoordinates(point: Vector): { x: number; y: number } { // Convert to Tile Space point point = this.transform.applyInverse(point); const x = Math.floor(point.x / this.tileWidth); const y = Math.floor(point.y / this.tileHeight); - return {x, y}; + return { x, y }; } public getRows(): readonly Tile[][] { @@ -506,30 +507,16 @@ export class TileMap extends Entity { worldBounds = worldBounds.translate(pos); } - const bounds = this.transform.coordPlane === CoordPlane.Screen ? - this._engine.screen.getScreenBounds() : - worldBounds; + const bounds = this.transform.coordPlane === CoordPlane.Screen ? this._engine.screen.getScreenBounds() : worldBounds; const topLeft = this._getTileCoordinates(bounds.topLeft); const topRight = this._getTileCoordinates(bounds.topRight); const bottomRight = this._getTileCoordinates(bounds.bottomRight); const bottomLeft = this._getTileCoordinates(bounds.bottomLeft); - const tileStartX = Math.min( - clamp(topLeft.x, 0, this.columns - 1), - clamp(topRight.x, 0, this.columns - 1) - ); - const tileStartY = Math.min( - clamp(topLeft.y, 0, this.rows - 1), - clamp(topRight.y, 0, this.rows - 1) - ); - const tileEndX = Math.max( - clamp(bottomRight.x, 0, this.columns - 1), - clamp(bottomLeft.x, 0, this.columns - 1) - ); - const tileEndY = Math.max( - clamp(bottomRight.y, 0, this.rows - 1), - clamp(bottomLeft.y, 0, this.rows - 1) - ); + const tileStartX = Math.min(clamp(topLeft.x, 0, this.columns - 1), clamp(topRight.x, 0, this.columns - 1)); + const tileStartY = Math.min(clamp(topLeft.y, 0, this.rows - 1), clamp(topRight.y, 0, this.rows - 1)); + const tileEndX = Math.max(clamp(bottomRight.x, 0, this.columns - 1), clamp(bottomLeft.x, 0, this.columns - 1)); + const tileEndY = Math.max(clamp(bottomRight.y, 0, this.rows - 1), clamp(bottomLeft.y, 0, this.rows - 1)); const tiles: Tile[] = []; for (let x = tileStartX; x <= tileEndX; x++) { @@ -544,9 +531,7 @@ export class TileMap extends Entity { this._initialize(engine); this.onPreUpdate(engine, delta); this.emit('preupdate', new PreUpdateEvent(engine, delta, this)); - if (!this._oldPos.equals(this.pos) || - this._oldRotation !== this.rotation || - !this._oldScale.equals(this.scale)) { + if (!this._oldPos.equals(this.pos) || this._oldRotation !== this.rotation || !this._oldScale.equals(this.scale)) { this.flagCollidersDirty(); this.flagTilesDirty(); } @@ -593,7 +578,7 @@ export class TileMap extends Entity { if (hasGraphicsTick(graphic)) { graphic?.tick(delta, this._token); } - const offsetY = this.renderFromTopOfGraphic ? 0 : (graphic.height - this.tileHeight); + const offsetY = this.renderFromTopOfGraphic ? 0 : graphic.height - this.tileHeight; graphic.draw(ctx, tile.x * this.tileWidth + offset.x, tile.y * this.tileHeight - offsetY + offset.y); } } @@ -611,11 +596,7 @@ export class TileMap extends Entity { solidBoundsColor: colliderBoundsColor, showColliderGeometry } = debugFlags.tilemap; - const { - geometryColor, - geometryLineWidth, - geometryPointSize - } = debugFlags.collider; + const { geometryColor, geometryLineWidth, geometryPointSize } = debugFlags.collider; const width = this.tileWidth * this.columns * this.scale.x; const height = this.tileHeight * this.rows * this.scale.y; const pos = this.pos; @@ -864,7 +845,7 @@ export class Tile { } public flagDirty() { - return this._posDirty = true; + return (this._posDirty = true); } private _recalculate() { @@ -874,10 +855,7 @@ export class Tile { this._width = this.map.tileWidth * this.map.scale.x; this._height = this.map.tileHeight * this.map.scale.y; - this._pos = this.map.pos.add( - vec( - this.x * this._width, - this.y * this._height)); + this._pos = this.map.pos.add(vec(this.x * this._width, this.y * this._height)); this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height); if (this.map.rotation) { @@ -910,29 +888,31 @@ export class Tile { return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2); } - public emit> - (eventName: TEventName, event: TilePointerEvents[TEventName]): void; + public emit>(eventName: TEventName, event: TilePointerEvents[TEventName]): void; public emit(eventName: string, event?: any): void; public emit | string>(eventName: TEventName, event?: any): void { this.events.emit(eventName, event); } - public on> - (eventName: TEventName, handler: Handler): Subscription; + public on>( + eventName: TEventName, + handler: Handler + ): Subscription; public on(eventName: string, handler: Handler): Subscription; public on | string>(eventName: TEventName, handler: Handler): Subscription { return this.events.on(eventName, handler); } - public once> - (eventName: TEventName, handler: Handler): Subscription; + public once>( + eventName: TEventName, + handler: Handler + ): Subscription; public once(eventName: string, handler: Handler): Subscription; public once | string>(eventName: TEventName, handler: Handler): Subscription { return this.events.once(eventName, handler); } - public off> - (eventName: TEventName, handler: Handler): void; + public off>(eventName: TEventName, handler: Handler): void; public off(eventName: string, handler: Handler): void; public off(eventName: string): void; public off | string>(eventName: TEventName, handler?: Handler): void { diff --git a/src/engine/TileMap/index.ts b/src/engine/TileMap/index.ts index 7e43bfb7..c1ce4f5f 100644 --- a/src/engine/TileMap/index.ts +++ b/src/engine/TileMap/index.ts @@ -1,4 +1,4 @@ export * from './TileMap'; export * from './IsometricMap'; export * from './IsometricEntityComponent'; -export * from './IsometricEntitySystem'; \ No newline at end of file +export * from './IsometricEntitySystem'; diff --git a/src/engine/Timer.ts b/src/engine/Timer.ts index 627e9805..7d65effc 100644 --- a/src/engine/Timer.ts +++ b/src/engine/Timer.ts @@ -3,7 +3,6 @@ import { Logger } from './Util/Log'; import * as ex from './index'; import { Random } from './Math/Random'; - export interface TimerOptions { repeats?: boolean; numberOfRepeats?: number; @@ -33,7 +32,7 @@ export class Timer { public interval: number = 10; public repeats: boolean = false; public maxNumberOfRepeats: number = -1; - public randomRange: [number, number] = [0,0]; + public randomRange: [number, number] = [0, 0]; public random: ex.Random; private _baseInterval = 10; private _generateRandomInterval = () => { @@ -55,8 +54,14 @@ export class Timer { * @param randomRange Indicates a range to select a random number to be added onto the interval */ constructor(options: TimerOptions); - constructor(fcn: TimerOptions | (() => void), interval?: number, - repeats?: boolean, numberOfRepeats?: number, randomRange?: [number, number], random?: ex.Random) { + constructor( + fcn: TimerOptions | (() => void), + interval?: number, + repeats?: boolean, + numberOfRepeats?: number, + randomRange?: [number, number], + random?: ex.Random + ) { if (typeof fcn !== 'function') { const options = fcn; fcn = options.fcn; @@ -64,7 +69,7 @@ export class Timer { repeats = options.repeats; numberOfRepeats = options.numberOfRepeats; randomRange = options.randomRange; - random= options.random; + random = options.random; } if (!!numberOfRepeats && numberOfRepeats >= 0) { @@ -77,7 +82,7 @@ export class Timer { this.id = Timer._MAX_ID++; this._callbacks = []; this._baseInterval = this.interval = interval; - if (!!randomRange){ + if (!!randomRange) { if (randomRange[0] > randomRange[1]) { throw new Error('min value must be lower than max value for range'); } @@ -89,7 +94,7 @@ export class Timer { this.on(() => { this.interval = this._generateRandomInterval(); }); - }; + } this.repeats = repeats || this.repeats; if (fcn) { this.on(fcn); @@ -152,7 +157,7 @@ export class Timer { */ public reset(newInterval?: number, newNumberOfRepeats?: number) { if (!!newInterval && newInterval >= 0) { - this._baseInterval = this.interval= newInterval; + this._baseInterval = this.interval = newInterval; } if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) { @@ -250,4 +255,3 @@ export class Timer { } } } - diff --git a/src/engine/Trigger.ts b/src/engine/Trigger.ts index d944f6f6..07892aa1 100644 --- a/src/engine/Trigger.ts +++ b/src/engine/Trigger.ts @@ -7,9 +7,9 @@ import { Actor, ActorEvents } from './Actor'; import { EventEmitter } from './EventEmitter'; export type TriggerEvents = ActorEvents & { - exit: ExitTriggerEvent, - enter: EnterTriggerEvent -} + exit: ExitTriggerEvent; + enter: EnterTriggerEvent; +}; export const TriggerEvents = { ExitTrigger: 'exit', diff --git a/src/engine/Util/Browser.ts b/src/engine/Util/Browser.ts index 680a268b..db58e697 100644 --- a/src/engine/Util/Browser.ts +++ b/src/engine/Util/Browser.ts @@ -50,7 +50,10 @@ export class BrowserComponent { export class BrowserEvents { private _windowComponent: BrowserComponent; private _documentComponent: BrowserComponent; - constructor(private _windowGlobal: Window, private _documentGlobal: Document) { + constructor( + private _windowGlobal: Window, + private _documentGlobal: Document + ) { this._windowComponent = new BrowserComponent(this._windowGlobal); this._documentComponent = new BrowserComponent(this._documentGlobal); } diff --git a/src/engine/Util/Clock.ts b/src/engine/Util/Clock.ts index 27047891..20e5d7a7 100644 --- a/src/engine/Util/Clock.ts +++ b/src/engine/Util/Clock.ts @@ -18,7 +18,6 @@ export interface ClockOptions { maxFps?: number; } - /** * Abstract Clock is the base type of all Clocks * @@ -31,7 +30,9 @@ export interface ClockOptions { */ export abstract class Clock { protected tick: (elapsedMs: number) => any; - private _onFatalException: (e: unknown) => any = () => { /* default nothing */ }; + private _onFatalException: (e: unknown) => any = () => { + /* default nothing */ + }; private _maxFps: number = Infinity; private _lastTime: number = 0; public fpsSampler: FpsSampler; @@ -123,13 +124,13 @@ export abstract class Clock { let elapsed = now - this._lastTime || 1; // first frame // Constrain fps - const fpsInterval = (1000 / this._maxFps); + const fpsInterval = 1000 / this._maxFps; // only run frame if enough time has elapsed if (elapsed >= fpsInterval) { let leftover = 0; if (fpsInterval !== 0) { - leftover = (elapsed % fpsInterval); + leftover = elapsed % fpsInterval; elapsed = elapsed - leftover; // shift elapsed to be "in phase" with the current loop fps } @@ -177,12 +178,10 @@ export abstract class Clock { public abstract stop(): void; } - /** * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick() */ export class StandardClock extends Clock { - private _running = false; private _requestId: number; constructor(options: ClockOptions) { @@ -289,4 +288,4 @@ export class TestClock extends Clock { this.step(overrideUpdateMs ?? this._updateMs); } } -} \ No newline at end of file +} diff --git a/src/engine/Util/Coroutine.ts b/src/engine/Util/Coroutine.ts index f51be03a..8a21498e 100644 --- a/src/engine/Util/Coroutine.ts +++ b/src/engine/Util/Coroutine.ts @@ -121,7 +121,8 @@ export function coroutine(...args: any[]): Promise { } catch (_) { throw Error( 'Cannot run coroutine without engine parameter outside of an excalibur lifecycle method.\n' + - 'Pass an engine parameter to ex.coroutine(engine, function * {...})'); + 'Pass an engine parameter to ex.coroutine(engine, function * {...})' + ); } const generatorFcn = coroutineGenerator.bind(thisArg); return new Promise((resolve, reject) => { @@ -138,7 +139,7 @@ export function coroutine(...args: any[]): Promise { // schedule next loop engine.clock.schedule(loop, 0, schedule); }); - } else if (value === undefined || value === (void 0)) { + } else if (value === undefined || value === void 0) { // schedule next frame engine.clock.schedule(loop, 0, schedule); } else { @@ -149,6 +150,6 @@ export function coroutine(...args: any[]): Promise { reject(e); } }; - loop(engine.clock.elapsed());// run first frame immediately + loop(engine.clock.elapsed()); // run first frame immediately }); -} \ No newline at end of file +} diff --git a/src/engine/Util/Detector.ts b/src/engine/Util/Detector.ts index b77d5206..52b85db5 100644 --- a/src/engine/Util/Detector.ts +++ b/src/engine/Util/Detector.ts @@ -140,13 +140,13 @@ export class Detector { // critical browser features required for ex to run private _criticalTests: CriticalTests = { // Test canvas/2d context support - canvasSupport: function() { + canvasSupport: function () { const elem = document.createElement('canvas'); return !!(elem.getContext && elem.getContext('2d')); }, // Test array buffer support ex uses for downloading binary data - arrayBufferSupport: function() { + arrayBufferSupport: function () { const xhr = new XMLHttpRequest(); xhr.open('GET', '/'); try { @@ -158,18 +158,18 @@ export class Detector { }, // Test data urls ex uses for sprites - dataUrlSupport: function() { + dataUrlSupport: function () { const canvas = document.createElement('canvas'); return canvas.toDataURL('image/png').indexOf('data:image/png') === 0; }, // Test object url support for loading - objectUrlSupport: function() { + objectUrlSupport: function () { return 'URL' in window && 'revokeObjectURL' in URL && 'createObjectURL' in URL; }, // RGBA support for colors - rgbaSupport: function() { + rgbaSupport: function () { const style = document.createElement('a').style; style.cssText = 'background-color:rgba(150,255,150,.5)'; return ('' + style.backgroundColor).indexOf('rgba') > -1; @@ -178,7 +178,7 @@ export class Detector { // warnings excalibur performance will be degraded private _warningTest: WarningTests = { - webAudioSupport: function() { + webAudioSupport: function () { return !!( (window).AudioContext || (window).webkitAudioContext || @@ -187,7 +187,7 @@ export class Detector { (window).oAudioContext ); }, - webglSupport: function() { + webglSupport: function () { const elem = document.createElement('canvas'); return !!(elem.getContext && elem.getContext('webgl')); } diff --git a/src/engine/Util/Fps.ts b/src/engine/Util/Fps.ts index d5bacdb7..1d918680 100644 --- a/src/engine/Util/Fps.ts +++ b/src/engine/Util/Fps.ts @@ -26,7 +26,7 @@ export class FpsSampler { constructor(options: FpsSamplerOptions) { this._fps = options.initialFps; this._samplePeriod = options.samplePeriod ?? this._samplePeriod; - this._currentFrameTime = 1000/options.initialFps; + this._currentFrameTime = 1000 / options.initialFps; this._nowFn = options.nowFn; this._previousSampleTime = this._nowFn(); } @@ -67,4 +67,4 @@ export class FpsSampler { get instant() { return 1000 / this._currentFrameTime; } -} \ No newline at end of file +} diff --git a/src/engine/Util/Future.ts b/src/engine/Util/Future.ts index 95292310..b48d058e 100644 --- a/src/engine/Util/Future.ts +++ b/src/engine/Util/Future.ts @@ -1,4 +1,3 @@ - /** * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time */ @@ -36,4 +35,4 @@ export class Future { this._isCompleted = true; this._rejecter(error); } -} \ No newline at end of file +} diff --git a/src/engine/Util/IFrame.ts b/src/engine/Util/IFrame.ts index 97459ace..18230d95 100644 --- a/src/engine/Util/IFrame.ts +++ b/src/engine/Util/IFrame.ts @@ -1,5 +1,3 @@ - - /** * Checks if excalibur is in a x-origin iframe */ @@ -20,4 +18,4 @@ export function isCrossOriginIframe() { return true; } return false; -} \ No newline at end of file +} diff --git a/src/engine/Util/Log.ts b/src/engine/Util/Log.ts index 4febbb0c..5d6ea986 100644 --- a/src/engine/Util/Log.ts +++ b/src/engine/Util/Log.ts @@ -83,7 +83,6 @@ export class Logger { } } - private _logOnceSet = new Set(); private _logOnce(level: LogLevel, args: any[]): void { const serialized = level + args.join('+'); @@ -263,7 +262,6 @@ export interface ScreenAppenderOptions { * On-screen (canvas) appender */ export class ScreenAppender implements Appender { - private _messages: string[] = []; public canvas: HTMLCanvasElement; private _ctx: CanvasRenderingContext2D; diff --git a/src/engine/Util/Required.ts b/src/engine/Util/Required.ts index d3707cae..04bd4ff5 100644 --- a/src/engine/Util/Required.ts +++ b/src/engine/Util/Required.ts @@ -1,3 +1,3 @@ export type DeepRequired = Required<{ - [K in keyof T]: T[K] extends Required ? T[K] : DeepRequired -}> \ No newline at end of file + [K in keyof T]: T[K] extends Required ? T[K] : DeepRequired; +}>; diff --git a/src/engine/Util/Semaphore.ts b/src/engine/Util/Semaphore.ts index 2b7b9ffc..fe660dcf 100644 --- a/src/engine/Util/Semaphore.ts +++ b/src/engine/Util/Semaphore.ts @@ -28,7 +28,7 @@ class AsyncWaitQueue { */ export class Semaphore { private _waitQueue = new AsyncWaitQueue(); - constructor(private _count: number) { } + constructor(private _count: number) {} public get count() { return this._count; @@ -57,4 +57,4 @@ export class Semaphore { } this._count += count; } -} \ No newline at end of file +} diff --git a/src/engine/Util/StateMachine.ts b/src/engine/Util/StateMachine.ts index b491c55c..6d29ac0e 100644 --- a/src/engine/Util/StateMachine.ts +++ b/src/engine/Util/StateMachine.ts @@ -1,16 +1,15 @@ - export interface State { name?: string; transitions: string[]; - onEnter?: (context: {from: string, eventData?: any, data: any}) => boolean | void; + onEnter?: (context: { from: string; eventData?: any; data: any }) => boolean | void; onState?: () => any; - onExit?: (context: {to: string, data: any}) => boolean | void; + onExit?: (context: { to: string; data: any }) => boolean | void; onUpdate?: (data: any, elapsedMs: number) => any; } export interface StateMachineDescription { - start: string, - states: { [name: string]: State } + start: string; + states: { [name: string]: State }; } export type PossibleStates = TMachine extends StateMachineDescription ? Extract : never; @@ -33,7 +32,9 @@ export class StateMachine { public data: TData; static create( - machineDescription: TMachine, data?: TData): StateMachine, TData> { + machineDescription: TMachine, + data?: TData + ): StateMachine, TData> { const machine = new StateMachine, TData>(); machine.data = data; for (const stateName in machineDescription.states) { @@ -68,14 +69,14 @@ export class StateMachine { if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes('*')) { const potentialNewState = this.states.get(stateName); if (this.currentState.onExit) { - const canExit = this.currentState?.onExit({to: potentialNewState.name, data: this.data}); + const canExit = this.currentState?.onExit({ to: potentialNewState.name, data: this.data }); if (canExit === false) { return false; } } if (potentialNewState?.onEnter) { - const canEnter = potentialNewState?.onEnter({from: this.currentState.name, eventData, data: this.data}); + const canEnter = potentialNewState?.onEnter({ from: this.currentState.name, eventData, data: this.data }); if (canEnter === false) { return false; } @@ -97,10 +98,13 @@ export class StateMachine { } save(saveKey: string) { - localStorage.setItem(saveKey, JSON.stringify({ - currentState: this.currentState.name, - data: this.data - })); + localStorage.setItem( + saveKey, + JSON.stringify({ + currentState: this.currentState.name, + data: this.data + }) + ); } restore(saveKey: string) { @@ -109,4 +113,3 @@ export class StateMachine { this.data = state.data; } } - diff --git a/src/engine/Util/Toaster.css b/src/engine/Util/Toaster.css index 186fadaa..c4881dde 100644 --- a/src/engine/Util/Toaster.css +++ b/src/engine/Util/Toaster.css @@ -1,4 +1,3 @@ - #ex-toast-container { position: absolute; height: 0; @@ -13,7 +12,6 @@ display: flex; justify-content: space-between; - padding: 10px; margin-top: 5px; font-size: 18px; @@ -23,7 +21,6 @@ background-color: rgb(253, 253, 192); } - .ex-toast-message button { align-self: flex-start; -} \ No newline at end of file +} diff --git a/src/engine/Util/Toaster.ts b/src/engine/Util/Toaster.ts index 52e1a308..c3814be2 100644 --- a/src/engine/Util/Toaster.ts +++ b/src/engine/Util/Toaster.ts @@ -47,7 +47,7 @@ export class Toaster { const toast = document.createElement('div'); toast.className = 'ex-toast-message'; - const messageFragments: HTMLElement[] = message.split('[LINK]').map(message => this._createFragment(message)); + const messageFragments: HTMLElement[] = message.split('[LINK]').map((message) => this._createFragment(message)); if (linkTarget) { const link = document.createElement('a'); @@ -62,7 +62,7 @@ export class Toaster { // Assembly message const finalMessage = document.createElement('div'); - messageFragments.forEach(message => { + messageFragments.forEach((message) => { finalMessage.appendChild(message); }); toast.appendChild(finalMessage); @@ -92,4 +92,4 @@ export class Toaster { const first = this._container.firstChild; this._container.insertBefore(toast, first); } -} \ No newline at end of file +} diff --git a/src/engine/Util/Util.ts b/src/engine/Util/Util.ts index 6a824f2b..6c322adf 100644 --- a/src/engine/Util/Util.ts +++ b/src/engine/Util/Util.ts @@ -81,7 +81,7 @@ export function delay(milliseconds: number, clock?: Clock): Promise { * @param object * @param keys */ -export function omit(object: TObject, keys: Keys[]) { +export function omit(object: TObject, keys: Keys[]) { const newObj: Omit = {} as any; for (const key in object) { if (!keys.includes(key as any)) { @@ -89,4 +89,4 @@ export function omit(objec } } return newObj; -} \ No newline at end of file +} diff --git a/src/engine/Util/Watch.ts b/src/engine/Util/Watch.ts index c6725f23..3c6c44c5 100644 --- a/src/engine/Util/Watch.ts +++ b/src/engine/Util/Watch.ts @@ -39,14 +39,11 @@ const createHandler = (path: string[] = [], change: (type: T) => any, typeTyp return true; } if (typeof (target as any)[key] === 'object' && (target as any)[key] != null) { - return new Proxy( - (target as any)[key], - createHandler([...path, key as string], change, typeType) - ); + return new Proxy((target as any)[key], createHandler([...path, key as string], change, typeType)); } return (target as any)[key]; }, - set: (target: T, key: string, value: any) => { + set: (target: T, key: string, value: any) => { if (typeof key === 'string') { if (key[0] !== '_') { change(typeType); diff --git a/src/engine/files.d.ts b/src/engine/files.d.ts index 6724cd19..5b685716 100644 --- a/src/engine/files.d.ts +++ b/src/engine/files.d.ts @@ -14,4 +14,4 @@ declare module '*.css' { declare module '*.glsl' { const value: string; export default value; -} \ No newline at end of file +} diff --git a/src/engine/globals.d.ts b/src/engine/globals.d.ts index 5a735753..8f14d461 100644 --- a/src/engine/globals.d.ts +++ b/src/engine/globals.d.ts @@ -17,4 +17,4 @@ declare const process: { env: { __EX_VERSION: string; }; -}; \ No newline at end of file +}; diff --git a/src/engine/index.ts b/src/engine/index.ts index 2301615e..04dedc07 100644 --- a/src/engine/index.ts +++ b/src/engine/index.ts @@ -56,30 +56,17 @@ export { events as Events }; import * as input from './Input/Index'; export { input as Input }; -export { - WheelEvent -} from './Input/WheelEvent'; - -export { - PointerEvent -} from './Input/PointerEvent'; +export { WheelEvent } from './Input/WheelEvent'; -export { - WheelDeltaMode -} from './Input/WheelDeltaMode'; +export { PointerEvent } from './Input/PointerEvent'; -export { - PointerButton -} from './Input/PointerButton'; +export { WheelDeltaMode } from './Input/WheelDeltaMode'; -export { - NativePointerButton -} from './Input/NativePointerButton'; +export { PointerButton } from './Input/PointerButton'; -export { - CapturePointerConfig -} from './Input/CapturePointerConfig'; +export { NativePointerButton } from './Input/NativePointerButton'; +export { CapturePointerConfig } from './Input/CapturePointerConfig'; export { NativePointerEvent, @@ -108,12 +95,7 @@ export { GamepadConfiguration } from './Input/Gamepad'; -export { - Keys, - KeyEvent, - KeyboardInitOptions, - Keyboard -} from './Input/Keyboard'; +export { Keys, KeyEvent, KeyboardInitOptions, Keyboard } from './Input/Keyboard'; export * from './Input/InputHost'; export * from './Input/InputMapper'; diff --git a/src/engine/tsconfig.json b/src/engine/tsconfig.json index 727bfddf..5610f236 100644 --- a/src/engine/tsconfig.json +++ b/src/engine/tsconfig.json @@ -18,12 +18,7 @@ "noUnusedParameters": false, "allowUnreachableCode": false, "downlevelIteration": true, - "lib": [ - "dom", - "dom.iterable", - "es5", - "es2018" - ], + "lib": ["dom", "dom.iterable", "es5", "es2018"], "types": [] } } diff --git a/src/spec/ActionSpec.ts b/src/spec/ActionSpec.ts index aefc3b22..8db9cd8d 100644 --- a/src/spec/ActionSpec.ts +++ b/src/spec/ActionSpec.ts @@ -33,44 +33,41 @@ describe('Action', () => { describe('parallel actions', () => { it('can run actions in parallel', () => { - const parallel = new ex.ParallelActions([ - new ex.MoveTo(actor, 100, 0, 100), - new ex.RotateTo(actor, Math.PI/2, Math.PI/2) - ]); + const parallel = new ex.ParallelActions([new ex.MoveTo(actor, 100, 0, 100), new ex.RotateTo(actor, Math.PI / 2, Math.PI / 2)]); actor.actions.runAction(parallel); scene.update(engine, 1000); expect(actor.pos).toBeVector(ex.vec(100, 0)); - expect(actor.rotation).toBe(Math.PI/2); + expect(actor.rotation).toBe(Math.PI / 2); }); it('can run sequences in parallel', () => { const parallel = new ex.ParallelActions([ - new ex.ActionSequence(actor, ctx => ctx.moveTo(ex.vec(100, 0), 100)), - new ex.ActionSequence(actor, ctx => ctx.rotateTo(Math.PI/2, Math.PI/2)) + new ex.ActionSequence(actor, (ctx) => ctx.moveTo(ex.vec(100, 0), 100)), + new ex.ActionSequence(actor, (ctx) => ctx.rotateTo(Math.PI / 2, Math.PI / 2)) ]); actor.actions.runAction(parallel); scene.update(engine, 1000); expect(actor.pos).toBeVector(ex.vec(100, 0)); - expect(actor.rotation).toBe(Math.PI/2); + expect(actor.rotation).toBe(Math.PI / 2); }); it('can repeat sequences in parallel', () => { const parallel = new ex.ParallelActions([ - new ex.ActionSequence(actor, ctx => ctx.moveTo(ex.vec(100, 0), 100).moveTo(ex.vec(0, 0), 100)), - new ex.ActionSequence(actor, ctx => ctx.rotateTo(Math.PI/2, Math.PI/2).rotateTo(0, Math.PI/2)) + new ex.ActionSequence(actor, (ctx) => ctx.moveTo(ex.vec(100, 0), 100).moveTo(ex.vec(0, 0), 100)), + new ex.ActionSequence(actor, (ctx) => ctx.rotateTo(Math.PI / 2, Math.PI / 2).rotateTo(0, Math.PI / 2)) ]); - actor.actions.repeatForever(ctx => { + actor.actions.repeatForever((ctx) => { ctx.runAction(parallel); }); scene.update(engine, 1000); expect(actor.pos).toBeVector(ex.vec(100, 0)); - expect(actor.rotation).toBe(Math.PI/2); + expect(actor.rotation).toBe(Math.PI / 2); scene.update(engine, 0); scene.update(engine, 1000); @@ -80,7 +77,7 @@ describe('Action', () => { scene.update(engine, 0); scene.update(engine, 1000); expect(actor.pos).toBeVector(ex.vec(100, 0)); - expect(actor.rotation).toBe(Math.PI/2); + expect(actor.rotation).toBe(Math.PI / 2); }); }); @@ -182,7 +179,6 @@ describe('Action', () => { }); it('can be reset', () => { - const blink = new ex.Blink(actor, 200, 200); blink.update(200); blink.update(200); @@ -450,7 +446,6 @@ describe('Action', () => { }); describe('easeBy', () => { - it('can be reset', () => { const easeTo = new ex.EaseBy(actor, 100, 0, 100, ex.EasingFunctions.EaseInOutCubic); easeTo.update(1000); @@ -881,7 +876,6 @@ describe('Action', () => { }); describe('rotateBy', () => { - it('can be reset', () => { const rotateBy = new ex.RotateBy(actor, Math.PI / 2, Math.PI / 2); actor.actions.runAction(rotateBy); @@ -1165,7 +1159,7 @@ describe('Action', () => { describe('meet', () => { it('can be reset', () => { - const target = new ex.Actor({x: 100, y: 0}); + const target = new ex.Actor({ x: 100, y: 0 }); const meet = new ex.Meet(actor, target, 100); actor.actions.runAction(meet); @@ -1201,7 +1195,6 @@ describe('Action', () => { }); describe('fade', () => { - it('can be reset', () => { const fade = new ex.Fade(actor, 0, 1000); fade.update(1000); diff --git a/src/spec/ActorSpec.ts b/src/spec/ActorSpec.ts index 9ef750fa..eb4eceb7 100644 --- a/src/spec/ActorSpec.ts +++ b/src/spec/ActorSpec.ts @@ -19,7 +19,7 @@ describe('A game actor', () => { beforeEach(async () => { engine = TestUtils.engine({ width: 100, height: 100 }); - actor = new ex.Actor({name: 'Default'}); + actor = new ex.Actor({ name: 'Default' }); actor.body.collisionType = ex.CollisionType.Active; scene = new ex.Scene(); const physicsWorld = new PhysicsWorld(engine.physics); @@ -33,7 +33,6 @@ describe('A game actor', () => { spyOn(scene, 'draw').and.callThrough(); spyOn(scene, 'debugDraw').and.callThrough(); - await engine.start(); const clock = engine.clock as ex.TestClock; clock.step(1); @@ -146,10 +145,10 @@ describe('A game actor', () => { }); it('should have constructor anchor set on graphics component', () => { - const actor = new ex.Actor({anchor: ex.vec(.7, .7)}); + const actor = new ex.Actor({ anchor: ex.vec(0.7, 0.7) }); - expect(actor.anchor).toBeVector(ex.vec(.7, .7)); - expect(actor.graphics.anchor).toBeVector(ex.vec(.7, .7)); + expect(actor.anchor).toBeVector(ex.vec(0.7, 0.7)); + expect(actor.graphics.anchor).toBeVector(ex.vec(0.7, 0.7)); actor.anchor = ex.vec(0, 0); expect(actor.graphics.anchor).toBeVector(ex.vec(0, 0)); @@ -602,7 +601,7 @@ describe('A game actor', () => { expect(grandChildActor.getGlobalPos().y).toBe(75); }); - it('can find its global coordinates if it doesn\'t have a parent', () => { + it("can find its global coordinates if it doesn't have a parent", () => { expect(actor.pos.x).toBe(0); expect(actor.pos.y).toBe(0); @@ -620,7 +619,7 @@ describe('A game actor', () => { const logger = ex.Logger.getInstance(); spyOn(logger, 'warn'); // attempt removing before adding - new ex.Actor({name: 'not-in-scene'}).kill(); + new ex.Actor({ name: 'not-in-scene' }).kill(); expect(logger.warn).toHaveBeenCalledWith('Cannot kill actor named "not-in-scene", it was never added to the Scene'); // remove actor in a scene @@ -679,7 +678,7 @@ describe('A game actor', () => { it('is drawn on opacity 0', () => { scene.clear(false); - const invisibleActor = new ex.Actor({name: 'Invisible', pos: ex.vec(50, 50), width: 100, height: 100}); + const invisibleActor = new ex.Actor({ name: 'Invisible', pos: ex.vec(50, 50), width: 100, height: 100 }); invisibleActor.graphics.onPostDraw = jasmine.createSpy('draw'); invisibleActor.graphics.opacity = 0; scene.add(invisibleActor); @@ -827,7 +826,7 @@ describe('A game actor', () => { flipHorizontal: false }); const animation = new ex.Animation({ - frames: [{graphic: sprite }, {graphic: sprite }], + frames: [{ graphic: sprite }, { graphic: sprite }], frameDuration: 200, strategy: ex.AnimationStrategy.Loop, rotation: Math.PI, @@ -996,8 +995,8 @@ describe('A game actor', () => { }); it('draws visible child actors', () => { - const parentActor = new ex.Actor({name: 'Parent'}); - const childActor = new ex.Actor({name: 'Child'}); + const parentActor = new ex.Actor({ name: 'Parent' }); + const childActor = new ex.Actor({ name: 'Child' }); scene.add(parentActor); parentActor.addChild(childActor); @@ -1389,7 +1388,6 @@ describe('A game actor', () => { expect(actor.onPreUpdate).toHaveBeenCalledTimes(2); }); - it('can have onPreKill overridden safely', () => { engine.add(actor); actor.onPreKill = (scene) => { diff --git a/src/spec/AffineMatrixSpec.ts b/src/spec/AffineMatrixSpec.ts index d0df9eb3..0293d115 100644 --- a/src/spec/AffineMatrixSpec.ts +++ b/src/spec/AffineMatrixSpec.ts @@ -131,9 +131,7 @@ describe('A AffineMatrix', () => { }); it('can find the affine inverse', () => { - const mat = ex.AffineMatrix.identity() - .translate(100, -200) - .scale(2, 4); + const mat = ex.AffineMatrix.identity().translate(100, -200).scale(2, 4); const inv = mat.inverse(); expect(mat.multiply(inv).isIdentity()).toBeTrue(); expect(inv.multiply(mat).isIdentity()).toBeTrue(); @@ -141,17 +139,14 @@ describe('A AffineMatrix', () => { it('can find the affine inverse and store it into a target', () => { const target = ex.AffineMatrix.identity(); - const mat = ex.AffineMatrix.identity() - .translate(100, -200) - .scale(2, 4); + const mat = ex.AffineMatrix.identity().translate(100, -200).scale(2, 4); spyOn(ex.AffineMatrix, 'identity'); const inv = mat.inverse(target); expect(mat.multiply(inv).isIdentity()).toBeTrue(); expect(inv.multiply(mat).isIdentity()).toBeTrue(); expect(target).toBe(inv); - expect(ex.AffineMatrix.identity).withContext('using a target doesnt create a new mat') - .not.toHaveBeenCalledWith(); + expect(ex.AffineMatrix.identity).withContext('using a target doesnt create a new mat').not.toHaveBeenCalledWith(); }); it('can clone into a target matrix', () => { @@ -160,11 +155,7 @@ describe('A AffineMatrix', () => { source.clone(destination); - expect(destination.data).toEqual(new Float64Array([ - 5, 0, - 0, 5, - 0, 0 - ])); + expect(destination.data).toEqual(new Float64Array([5, 0, 0, 5, 0, 0])); }); it('can set position', () => { @@ -175,7 +166,7 @@ describe('A AffineMatrix', () => { }); it('can convert to a 4x4 matrix', () => { - const mat = ex.AffineMatrix.identity().translate(1,2).rotate(Math.PI).scale(3, 4); + const mat = ex.AffineMatrix.identity().translate(1, 2).rotate(Math.PI).scale(3, 4); expect(mat.getPosition()).toBeVector(ex.vec(1, 2)); expect(mat.getRotation()).toBe(Math.PI); expect(mat.getScale()).toBeVector(ex.vec(3, 4)); @@ -187,9 +178,7 @@ describe('A AffineMatrix', () => { }); it('can reset to identity', () => { - const mat = ex.AffineMatrix.identity() - .translate(100, -200) - .scale(2, 4); + const mat = ex.AffineMatrix.identity().translate(100, -200).scale(2, 4); mat.reset(); expect(mat.isIdentity()).toBe(true); @@ -203,4 +192,4 @@ describe('A AffineMatrix', () => { [0 0 1] `); }); -}); \ No newline at end of file +}); diff --git a/src/spec/AlgebraSpec.ts b/src/spec/AlgebraSpec.ts index 41c903f2..cbe27712 100644 --- a/src/spec/AlgebraSpec.ts +++ b/src/spec/AlgebraSpec.ts @@ -58,7 +58,6 @@ describe('Vectors', () => { }); it('will return toAngle between 0 and 2PI', () => { - const zero = ex.vec(1, 0); expect(zero.toAngle()).toBeCloseTo(0); @@ -69,23 +68,22 @@ describe('Vectors', () => { expect(ninety.toAngle()).toBeCloseTo(Math.PI / 2); const oneThirtyFive = ex.vec(-1, 1); - expect(oneThirtyFive.toAngle()).toBeCloseTo(Math.PI * 3 / 4); + expect(oneThirtyFive.toAngle()).toBeCloseTo((Math.PI * 3) / 4); const oneEighty = ex.vec(-1, 0); expect(oneEighty.toAngle()).toBeCloseTo(Math.PI); const twoTwentyFive = ex.vec(-1, -1); - expect(twoTwentyFive.toAngle()).toBeCloseTo(Math.PI * 5 / 4); + expect(twoTwentyFive.toAngle()).toBeCloseTo((Math.PI * 5) / 4); const twoSeventy = ex.vec(0, -1); - expect(twoSeventy.toAngle()).toBeCloseTo(Math.PI * 3 / 2); + expect(twoSeventy.toAngle()).toBeCloseTo((Math.PI * 3) / 2); const threeFifteen = ex.vec(1, -1); - expect(threeFifteen.toAngle()).toBeCloseTo(Math.PI * 7 / 4); + expect(threeFifteen.toAngle()).toBeCloseTo((Math.PI * 7) / 4); const threeSixty = ex.vec(1, -0.0001); expect(threeSixty.toAngle()).toBeCloseTo(Math.PI * 2); - }); it('can calculate distance to origin', () => { diff --git a/src/spec/AnimationSpec.ts b/src/spec/AnimationSpec.ts index 63bd1c4a..0890d9e2 100644 --- a/src/spec/AnimationSpec.ts +++ b/src/spec/AnimationSpec.ts @@ -86,10 +86,10 @@ describe('A Graphics Animation', () => { const anim = ex.Animation.fromSpriteSheetCoordinates({ spriteSheet: ss, frameCoordinates: [ - {x: 0, y: 0, duration: 100, options: { flipHorizontal: true }}, - {x: 1, y: 0, duration: 100, options: { flipVertical: true }}, - {x: 2, y: 0, duration: 100}, - {x: 3, y: 0, duration: 100} + { x: 0, y: 0, duration: 100, options: { flipHorizontal: true } }, + { x: 1, y: 0, duration: 100, options: { flipVertical: true } }, + { x: 2, y: 0, duration: 100 }, + { x: 3, y: 0, duration: 100 } ], strategy: ex.AnimationStrategy.Freeze }); @@ -520,7 +520,6 @@ describe('A Graphics Animation', () => { }); it('calculate automatically the frame duration based on the animation total duration', () => { - const rect = new ex.Rectangle({ width: 100, height: 100, @@ -551,7 +550,6 @@ describe('A Graphics Animation', () => { }); it('has a current time left in a frame', () => { - const rect = new ex.Rectangle({ width: 100, height: 100, @@ -585,7 +583,6 @@ describe('A Graphics Animation', () => { }); it('reset will reset time in frame', () => { - const rect = new ex.Rectangle({ width: 100, height: 100, diff --git a/src/spec/ArcadeSolverSpec.ts b/src/spec/ArcadeSolverSpec.ts index 34c988e5..faddf932 100644 --- a/src/spec/ArcadeSolverSpec.ts +++ b/src/spec/ArcadeSolverSpec.ts @@ -12,12 +12,11 @@ describe('An ArcadeSolver', () => { expect(ex.ArcadeSolver).toBeDefined(); }); - it('should only solve position for overlapping contacts', ()=> { + it('should only solve position for overlapping contacts', () => { + const wall1 = new ex.Actor({ x: 0, y: 0, width: 100, height: 100, collisionType: ex.CollisionType.Fixed }); + const wall2 = new ex.Actor({ x: 100, y: 0, width: 100, height: 100, collisionType: ex.CollisionType.Fixed }); - const wall1 = new ex.Actor({x: 0, y: 0, width: 100, height: 100, collisionType: ex.CollisionType.Fixed}); - const wall2 = new ex.Actor({x: 100, y: 0, width: 100, height: 100, collisionType: ex.CollisionType.Fixed}); - - const player = new ex.Actor({x: 50, y: 99, width: 100, height: 100, collisionType: ex.CollisionType.Active}); + const player = new ex.Actor({ x: 50, y: 99, width: 100, height: 100, collisionType: ex.CollisionType.Active }); const pair1 = new ex.Pair(player.collider.get(), wall1.collider.get()); const pair2 = new ex.Pair(player.collider.get(), wall2.collider.get()); @@ -77,7 +76,7 @@ describe('An ArcadeSolver', () => { game.add(player); // run simulation and ensure now left/right contacts are generated - player.on('postcollision', evt => { + player.on('postcollision', (evt) => { expect(evt.side).not.toBe(ex.Side.Left); expect(evt.side).not.toBe(ex.Side.Right); expect(evt.side).toBe(ex.Side.Bottom); @@ -117,19 +116,34 @@ describe('An ArcadeSolver', () => { // 1 pixel overlap const contact = new ex.CollisionContact( - player.collider.get(), block.collider.get(), ex.Vector.Down, ex.Vector.Down, ex.Vector.Down.perpendicular(), [], [], null); + player.collider.get(), + block.collider.get(), + ex.Vector.Down, + ex.Vector.Down, + ex.Vector.Down.perpendicular(), + [], + [], + null + ); arcadeSolver.solvePosition(contact); expect(player.pos).toBeVector(ex.vec(0, -1)); // No more overlap const contact2 = new ex.CollisionContact( - player.collider.get(), block.collider.get(), ex.Vector.Down, ex.Vector.Down, ex.Vector.Down.perpendicular(), [], [], null); + player.collider.get(), + block.collider.get(), + ex.Vector.Down, + ex.Vector.Down, + ex.Vector.Down.perpendicular(), + [], + [], + null + ); arcadeSolver.solvePosition(contact2); expect(contact2.isCanceled()).toBeTrue(); }); it('should NOT cancel collisions where the bodies are moving away from the contact', () => { - const arcadeSolver = new ex.ArcadeSolver(DefaultPhysicsConfig.arcade); const player = new ex.Actor({ @@ -153,7 +167,15 @@ describe('An ArcadeSolver', () => { // Player moving away from contact const contact = new ex.CollisionContact( - player.collider.get(), block.collider.get(), ex.Vector.Down, ex.Vector.Down, ex.Vector.Up.perpendicular(), [], [], null); + player.collider.get(), + block.collider.get(), + ex.Vector.Down, + ex.Vector.Down, + ex.Vector.Up.perpendicular(), + [], + [], + null + ); arcadeSolver.solveVelocity(contact); expect(contact.isCanceled()).toBeFalse(); expect(player.vel).toBeVector(ex.vec(0, -10)); // Velocity is not adjusted @@ -161,7 +183,15 @@ describe('An ArcadeSolver', () => { // Player moving towards contact player.vel = player.vel.negate(); const contact2 = new ex.CollisionContact( - player.collider.get(), block.collider.get(), ex.Vector.Down, ex.Vector.Down, ex.Vector.Down.perpendicular(), [], [], null); + player.collider.get(), + block.collider.get(), + ex.Vector.Down, + ex.Vector.Down, + ex.Vector.Down.perpendicular(), + [], + [], + null + ); arcadeSolver.solveVelocity(contact2); expect(contact2.isCanceled()).toBeFalse(); @@ -192,7 +222,7 @@ describe('An ArcadeSolver', () => { const contact = new ex.CollisionContact( player.collider.get(), block.collider.get(), - ex.Vector.Down.scale(.00009), + ex.Vector.Down.scale(0.00009), ex.Vector.Down, ex.Vector.Up.perpendicular(), [], @@ -220,14 +250,22 @@ describe('An ArcadeSolver', () => { const block = new ex.Actor({ x: 40, y: 0, - width: 40 + .00005, + width: 40 + 0.00005, height: 40, collisionType: ex.CollisionType.Fixed, color: ex.Color.Green }); const contact = new ex.CollisionContact( - player.collider.get(), block.collider.get(), ex.Vector.Down, ex.Vector.Down, ex.Vector.Up.perpendicular(), [], [], null); + player.collider.get(), + block.collider.get(), + ex.Vector.Down, + ex.Vector.Down, + ex.Vector.Up.perpendicular(), + [], + [], + null + ); arcadeSolver.solvePosition(contact); // Considers infinitesimally overlapping to no longer be overlapping and thus cancels the contact @@ -249,14 +287,22 @@ describe('An ArcadeSolver', () => { const block = new ex.Actor({ x: 40, y: 0, - width: 40 + .00005, + width: 40 + 0.00005, height: 40, collisionType: ex.CollisionType.Fixed, color: ex.Color.Green }); const contact = new ex.CollisionContact( - player.collider.get(), block.collider.get(), ex.Vector.Down, ex.Vector.Down, ex.Vector.Up.perpendicular(), [], [], null); + player.collider.get(), + block.collider.get(), + ex.Vector.Down, + ex.Vector.Down, + ex.Vector.Up.perpendicular(), + [], + [], + null + ); contact.mtv = ex.vec(-0, 0); @@ -283,7 +329,7 @@ describe('An ArcadeSolver', () => { // big tiles so distance heuristic doesn't work const lastPos = ex.vec(0, 0); for (let x = 0; x < 10; x++) { - const width = (x % 2 === 1 ? 16 : 200); + const width = x % 2 === 1 ? 16 : 200; game.add( new ex.Actor({ name: 'floor-tile', @@ -312,7 +358,7 @@ describe('An ArcadeSolver', () => { game.add(player); // run simulation and ensure now left/right contacts are generated - player.on('postcollision', evt => { + player.on('postcollision', (evt) => { expect(evt.side).not.toBe(ex.Side.Left); expect(evt.side).not.toBe(ex.Side.Right); expect(evt.side).toBe(ex.Side.Bottom); @@ -324,4 +370,4 @@ describe('An ArcadeSolver', () => { game.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/BodyComponentSpec.ts b/src/spec/BodyComponentSpec.ts index 783a43e2..cf7554af 100644 --- a/src/spec/BodyComponentSpec.ts +++ b/src/spec/BodyComponentSpec.ts @@ -11,7 +11,6 @@ describe('A body component', () => { }); it('can set the mass and cache their values', () => { - const actor = new ex.Actor({ x: 0, y: 0, @@ -23,7 +22,7 @@ describe('A body component', () => { expect(actor.body.mass).toBe(100); expect(actor.body.inertia).toBeCloseTo(1666.6, 0); - expect(actor.body.inverseInertia).toBeCloseTo(.0006, 0); + expect(actor.body.inverseInertia).toBeCloseTo(0.0006, 0); expect((actor.body as any)._cachedInertia).toBeCloseTo(1666.6, 0); expect((actor.body as any)._cachedInverseInertia).toBeCloseTo(0.0006, 0); @@ -58,7 +57,7 @@ describe('A body component', () => { body.mass = 100; body.canSleep = true; body.bounciness = 1; - body.friction = .5; + body.friction = 0.5; body.useGravity = false; body.limitDegreeOfFreedom.push(ex.DegreeOfFreedom.Rotation); body.vel = ex.vec(1, 2); @@ -96,5 +95,4 @@ describe('A body component', () => { // Should have a new owner expect(sut.owner).toBe(clone); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/BoundingBoxSpec.ts b/src/spec/BoundingBoxSpec.ts index 1c91c6dd..71e5f849 100644 --- a/src/spec/BoundingBoxSpec.ts +++ b/src/spec/BoundingBoxSpec.ts @@ -117,7 +117,7 @@ function runBoundingBoxTests(creationType: string, createBoundingBox: Function) }); it('can overlap with other bounding boxes', () => { - const b1 = new ex.BoundingBox({left: 100, right: 110, top: 100, bottom: 110}); + const b1 = new ex.BoundingBox({ left: 100, right: 110, top: 100, bottom: 110 }); const b2 = new ex.BoundingBox(2, 0, 20, 10); const b3 = new ex.BoundingBox(12, 0, 28, 10); expect(b2.overlaps(b3)).toBe(true); @@ -147,10 +147,9 @@ function runBoundingBoxTests(creationType: string, createBoundingBox: Function) expect(bb1.overlaps(bbMid)).toBe(true); expect(bbMid.overlaps(bb1)).toBe(true); - const bb3 = new ex.BoundingBox({left: -1, top: 0, bottom: 0, right: -1}); + const bb3 = new ex.BoundingBox({ left: -1, top: 0, bottom: 0, right: -1 }); expect(bb3.overlaps(bb1)).toBe(false); expect(bb1.overlaps(bb3)).toBe(false); - }); it('can overlap with a margin for floating point rounding to consider no longer overlap', () => { @@ -163,7 +162,7 @@ function runBoundingBoxTests(creationType: string, createBoundingBox: Function) // bb2 is very technically overlapping, but very slightly and we want to consider it not really overlapping const bb2 = new ex.BoundingBox({ - left: 100 - 0.00001, + left: 100 - 0.00001, right: 200 - 0.00001, top: 0, bottom: 100 diff --git a/src/spec/CameraSpec.ts b/src/spec/CameraSpec.ts index a0def968..7ae83a9b 100644 --- a/src/spec/CameraSpec.ts +++ b/src/spec/CameraSpec.ts @@ -45,11 +45,11 @@ describe('A camera', () => { engine.dispose(); engine = null; engine = TestUtils.engine({ - viewport: {width: 100, height: 100}, - resolution: {width: 1000, height: 1200 } + viewport: { width: 100, height: 100 }, + resolution: { width: 1000, height: 1200 } }); engine.screen.pushResolutionAndViewport(); - engine.screen.resolution = {width: 100, height: 1000}; + engine.screen.resolution = { width: 100, height: 1000 }; spyOnProperty(engine, 'loadingComplete', 'get').and.returnValue(false); spyOn(engine.screen, 'peekResolution').and.callThrough(); @@ -65,8 +65,8 @@ describe('A camera', () => { engine.dispose(); engine = null; engine = TestUtils.engine({ - viewport: {width: 100, height: 100}, - resolution: {width: 1000, height: 1200 } + viewport: { width: 100, height: 100 }, + resolution: { width: 1000, height: 1200 } }); const sut = new ex.Camera(); @@ -81,8 +81,8 @@ describe('A camera', () => { engine.dispose(); engine = null; engine = TestUtils.engine({ - viewport: {width: 100, height: 100}, - resolution: {width: 1000, height: 1200 } + viewport: { width: 100, height: 100 }, + resolution: { width: 1000, height: 1200 } }); const sut = new ex.Camera(); @@ -98,8 +98,8 @@ describe('A camera', () => { engine.dispose(); engine = null; engine = TestUtils.engine({ - viewport: {width: 100, height: 100}, - resolution: {width: 1000, height: 1200 } + viewport: { width: 100, height: 100 }, + resolution: { width: 1000, height: 1200 } }); spyOnProperty(engine, 'loadingComplete', 'get').and.returnValue(true); @@ -275,7 +275,7 @@ describe('A camera', () => { it('can use built-in locked camera x axis strategy', () => { engine.currentScene.camera = new ex.Camera(); engine.currentScene.camera.pos = ex.Vector.Zero; - const actor = new ex.Actor({x: 0, y: 0}); + const actor = new ex.Actor({ x: 0, y: 0 }); engine.currentScene.camera.strategy.lockToActorAxis(actor, ex.Axis.X); @@ -292,7 +292,7 @@ describe('A camera', () => { it('can use built-in locked camera y axis strategy', () => { engine.currentScene.camera = new ex.Camera(); engine.currentScene.camera.pos = ex.Vector.Zero; - const actor = new ex.Actor({x: 0, y: 0}); + const actor = new ex.Actor({ x: 0, y: 0 }); engine.currentScene.camera.strategy.lockToActorAxis(actor, ex.Axis.Y); @@ -309,7 +309,7 @@ describe('A camera', () => { it('can use built-in radius around actor strategy', () => { engine.currentScene.camera = new ex.Camera(); engine.currentScene.camera.pos = ex.Vector.Zero; - const actor = new ex.Actor({x: 0, y: 0}); + const actor = new ex.Actor({ x: 0, y: 0 }); engine.currentScene.camera.strategy.radiusAroundActor(actor, 15); diff --git a/src/spec/CanvasSpec.ts b/src/spec/CanvasSpec.ts index 740c7575..b9b43d49 100644 --- a/src/spec/CanvasSpec.ts +++ b/src/spec/CanvasSpec.ts @@ -109,7 +109,7 @@ describe('A Canvas Graphic', () => { }); it('can be centered with the specified dimensions in an actor', async () => { - const engine = TestUtils.engine({width: 100, height: 100}); + const engine = TestUtils.engine({ width: 100, height: 100 }); const clock = engine.clock as ex.TestClock; await TestUtils.runToReady(engine); const sut = new ex.Canvas({ diff --git a/src/spec/ClockSpec.ts b/src/spec/ClockSpec.ts index b80fc93b..e2e70179 100644 --- a/src/spec/ClockSpec.ts +++ b/src/spec/ClockSpec.ts @@ -33,7 +33,9 @@ describe('Clocks', () => { it('can be converted to a standard clock', () => { const testClock = new ex.TestClock({ - tick: () => { /* nothing */ }, + tick: () => { + /* nothing */ + }, defaultUpdateMs: 1000 }); @@ -46,7 +48,9 @@ describe('Clocks', () => { spyOn(logger, 'warn'); const testClock = new ex.TestClock({ - tick: () => { /* nothing */ }, + tick: () => { + /* nothing */ + }, defaultUpdateMs: 1000 }); @@ -57,7 +61,9 @@ describe('Clocks', () => { it('works with delay()', (done) => { const testClock = new ex.TestClock({ - tick: () => { /* nothing */ }, + tick: () => { + /* nothing */ + }, defaultUpdateMs: 1000 }); testClock.start(); @@ -71,7 +77,9 @@ describe('Clocks', () => { it('can schedule a callbacks to fire', async () => { const testClock = new ex.TestClock({ - tick: () => { /* nothing */ }, + tick: () => { + /* nothing */ + }, defaultUpdateMs: 1000 }); testClock.start(); @@ -154,7 +162,9 @@ describe('Clocks', () => { it('can return the elapsed time', () => { const clock = new ex.StandardClock({ - tick: () => { /* nothing */ } + tick: () => { + /* nothing */ + } }); (clock as any).update(100); expect(clock.elapsed()).toBe(100); @@ -162,7 +172,9 @@ describe('Clocks', () => { it('can be converted to a test clock', () => { const clock = new ex.StandardClock({ - tick: () => { /* nothing */ } + tick: () => { + /* nothing */ + } }); const test = clock.toTestClock(); @@ -170,4 +182,4 @@ describe('Clocks', () => { expect(test).toBeInstanceOf(ex.TestClock); }); }); -}); \ No newline at end of file +}); diff --git a/src/spec/ColliderComponentSpec.ts b/src/spec/ColliderComponentSpec.ts index 8c3f3d48..e6858f65 100644 --- a/src/spec/ColliderComponentSpec.ts +++ b/src/spec/ColliderComponentSpec.ts @@ -42,12 +42,9 @@ describe('A ColliderComponent', () => { expect(sut.owner).toBe(clone); // Original handler should fire not the clone - collider.get().events.emit('collisionstart', - new ex.CollisionStartEvent( - ex.Shape.Circle(50), - ex.Shape.Circle(50), - null, - null)); + collider + .get() + .events.emit('collisionstart', new ex.CollisionStartEvent(ex.Shape.Circle(50), ex.Shape.Circle(50), null, null)); expect(originalCollisionHandler).toHaveBeenCalledTimes(1); expect(cloneCollisionHandler).not.toHaveBeenCalled(); diff --git a/src/spec/CollisionContactSpec.ts b/src/spec/CollisionContactSpec.ts index 060fa75d..5e9d7487 100644 --- a/src/spec/CollisionContactSpec.ts +++ b/src/spec/CollisionContactSpec.ts @@ -11,21 +11,18 @@ describe('A CollisionContact', () => { let colliderA: ex.Collider; let colliderB: ex.Collider; - beforeEach(() => { - actorA = new ex.Actor({x: 0, y: 0, width: 20, height: 20}); + actorA = new ex.Actor({ x: 0, y: 0, width: 20, height: 20 }); actorA.collider.useCircleCollider(10); actorA.body.collisionType = ex.CollisionType.Active; - actorB = new ex.Actor({x: 20, y: 0, width: 20, height: 20}); + actorB = new ex.Actor({ x: 20, y: 0, width: 20, height: 20 }); actorB.collider.useCircleCollider(10); - actorB.body.collisionType = ex.CollisionType.Active; colliderA = actorA.collider.get(); colliderB = actorB.collider.get(); - }); it('exists', () => { @@ -70,7 +67,6 @@ describe('A CollisionContact', () => { }); it('emits a collision event on both actors in the Arcade solver', () => { - const actorAPreCollide = jasmine.createSpy('precollision A'); const actorBPreCollide = jasmine.createSpy('precollision B'); actorA.on('precollision', actorAPreCollide); @@ -121,14 +117,13 @@ describe('A CollisionContact', () => { null ); // slop is normally 1 pixel, we are testing at a pixel scale here - const solver = new ex.RealisticSolver({...DefaultPhysicsConfig.realistic, slop: 0}); + const solver = new ex.RealisticSolver({ ...DefaultPhysicsConfig.realistic, slop: 0 }); // Realistic solver converges over time for (let i = 0; i < 4; i++) { solver.solve([cc]); // Realistic solver uses velocity impulses to correct overlap EulerIntegrator.integrate(actorA.get(TransformComponent), actorA.get(MotionComponent), ex.Vector.Zero, 1000); EulerIntegrator.integrate(actorB.get(TransformComponent), actorB.get(MotionComponent), ex.Vector.Zero, 1000); - } expect(actorA.pos.x).toBeCloseTo(-0.5, 1); @@ -167,7 +162,7 @@ describe('A CollisionContact', () => { null ); // slop is normally 1 pixel, we are testing at a pixel scale here - const solver = new ex.RealisticSolver({ ...DefaultPhysicsConfig.realistic, slop: 0}); + const solver = new ex.RealisticSolver({ ...DefaultPhysicsConfig.realistic, slop: 0 }); solver.solve([cc]); // Realistic solver uses velocity impulses to correct overlap @@ -324,7 +319,6 @@ describe('A CollisionContact', () => { null ); - const solver = new ex.RealisticSolver(DefaultPhysicsConfig.realistic); solver.solve([cc]); diff --git a/src/spec/CollisionShapeSpec.ts b/src/spec/CollisionShapeSpec.ts index 67c0af37..64f954e9 100644 --- a/src/spec/CollisionShapeSpec.ts +++ b/src/spec/CollisionShapeSpec.ts @@ -69,7 +69,6 @@ describe('Collision Shape', () => { }); it('has a radius based on scale', () => { - const sut = circle.clone(); expect(sut.radius).toBe(10); @@ -106,12 +105,14 @@ describe('Collision Shape', () => { expect(sut.bounds.top).toBeCloseTo(expected.top); expect(sut.bounds.bottom).toBeCloseTo(expected.bottom); - expect(sut.localBounds).toEqual(new ex.BoundingBox({ - left: 90, - top: -10, - bottom: 10, - right: 110 - })); + expect(sut.localBounds).toEqual( + new ex.BoundingBox({ + left: 90, + top: -10, + bottom: 10, + right: 110 + }) + ); }); it('calculates correct center when transformed', () => { @@ -179,7 +180,7 @@ describe('Collision Shape', () => { expect(point.y).toBe(0); }); - it('doesn\'t have axes', () => { + it("doesn't have axes", () => { // technically circles have infinite axes expect(circle.axes).toEqual([]); }); @@ -956,10 +957,9 @@ describe('Collision Shape', () => { expect(edge.bounds.bottom).toBe(30); }); - it('can be rotated', () => { const transform = new ex.Transform(); - transform.rotation = Math.PI/2; + transform.rotation = Math.PI / 2; const edge = new ex.EdgeCollider({ begin: ex.vec(0, 0), end: ex.vec(0, 10), @@ -1051,9 +1051,7 @@ describe('Collision Shape', () => { const edge = ex.Shape.Edge(ex.vec(-100, 30), ex.vec(100, 30)); const circle = ex.Shape.Circle(30); const contact = circle.collide(edge)[0]; - expect(contact.normal) - .withContext('Circle/Edge normals point away from circle') - .toBeVector(ex.Vector.Down); + expect(contact.normal).withContext('Circle/Edge normals point away from circle').toBeVector(ex.Vector.Down); expect(contact.points[0]).toBeVector(ex.vec(0, 30)); expect(contact.info.collider).toBe(circle); expect(contact.info.point).toBeVector(ex.vec(0, 30)); @@ -1066,9 +1064,7 @@ describe('Collision Shape', () => { const edge = ex.Shape.Edge(ex.vec(30, 0), ex.vec(100, 0)); const circle = ex.Shape.Circle(30); const contact = circle.collide(edge)[0]; - expect(contact.normal) - .withContext('Circle/Edge normals point away from circle') - .toBeVector(ex.Vector.Right); + expect(contact.normal).withContext('Circle/Edge normals point away from circle').toBeVector(ex.Vector.Right); expect(contact.points[0]).toBeVector(ex.vec(30, 0)); expect(contact.info.collider).toBe(circle); expect(contact.info.point).toBeVector(ex.vec(30, 0)); @@ -1081,9 +1077,7 @@ describe('Collision Shape', () => { const edge = ex.Shape.Edge(ex.vec(-100, 0), ex.vec(-30, 0)); const circle = ex.Shape.Circle(30); const contact = circle.collide(edge)[0]; - expect(contact.normal) - .withContext('Circle/Edge normals point away from circle') - .toBeVector(ex.Vector.Left); + expect(contact.normal).withContext('Circle/Edge normals point away from circle').toBeVector(ex.Vector.Left); expect(contact.points[0]).toBeVector(ex.vec(-30, 0)); expect(contact.info.collider).toBe(circle); expect(contact.info.point).toBeVector(ex.vec(-30, 0)); @@ -1096,9 +1090,7 @@ describe('Collision Shape', () => { const edge = ex.Shape.Edge(ex.vec(-100, -30), ex.vec(100, -30)); const circle = ex.Shape.Circle(30); const contact = circle.collide(edge)[0]; - expect(contact.normal) - .withContext('Circle/Edge normals point away from circle') - .toBeVector(ex.Vector.Up); + expect(contact.normal).withContext('Circle/Edge normals point away from circle').toBeVector(ex.Vector.Up); expect(contact.points[0]).toBeVector(ex.vec(0, -30)); expect(contact.info.collider).toBe(circle); expect(contact.info.point).toBeVector(ex.vec(0, -30)); @@ -1111,9 +1103,7 @@ describe('Collision Shape', () => { const edge = ex.Shape.Edge(ex.vec(-100, 10), ex.vec(100, 10)); const rect = ex.Shape.Box(40, 20, ex.Vector.Half); const contact = rect.collide(edge)[0]; - expect(contact.normal) - .withContext('Rect/Edge normal point away from edge') - .toBeVector(ex.Vector.Down); + expect(contact.normal).withContext('Rect/Edge normal point away from edge').toBeVector(ex.Vector.Down); expect(contact.points[0]).toBeVector(ex.vec(20, 10)); expect(contact.points[1]).toBeVector(ex.vec(-20, 10)); @@ -1125,9 +1115,7 @@ describe('Collision Shape', () => { const edge = ex.Shape.Edge(ex.vec(10, 10), ex.vec(100, 10)); const rect = ex.Shape.Box(40, 20, ex.Vector.Half); const contact = rect.collide(edge)[0]; - expect(contact.normal) - .withContext('Rect/Edge normal point away from edge') - .toBeVector(ex.Vector.Down); + expect(contact.normal).withContext('Rect/Edge normal point away from edge').toBeVector(ex.Vector.Down); expect(contact.points[0]).toBeVector(ex.vec(20, 10)); expect(contact.points[1]).toBeVector(ex.vec(10, 10)); @@ -1139,9 +1127,7 @@ describe('Collision Shape', () => { const edge = ex.Shape.Edge(ex.vec(-100, 10), ex.vec(0, 10)); const rect = ex.Shape.Box(40, 20, ex.Vector.Half); const contact = rect.collide(edge)[0]; - expect(contact.normal) - .withContext('Rect/Edge normal point away from edge') - .toBeVector(ex.Vector.Down); + expect(contact.normal).withContext('Rect/Edge normal point away from edge').toBeVector(ex.Vector.Down); expect(contact.points[0]).toBeVector(ex.vec(-20, 10)); expect(contact.points[1]).toBeVector(ex.vec(0, 10)); @@ -1168,7 +1154,8 @@ describe('Collision Shape', () => { spyOn(logger, 'warn'); const sut = ex.Shape.Capsule(100, 100); expect(logger.warn).toHaveBeenCalledWith( - 'A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider'); + 'A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider' + ); }); it('can be defined with an offset horizontally', () => { diff --git a/src/spec/CollisionSpec.ts b/src/spec/CollisionSpec.ts index 0b1fc97c..661d018b 100644 --- a/src/spec/CollisionSpec.ts +++ b/src/spec/CollisionSpec.ts @@ -12,8 +12,8 @@ describe('A Collision', () => { engine = TestUtils.engine({ width: 600, height: 400 }); clock = engine.clock = engine.clock.toTestClock(); - actor1 = new ex.Actor({x: 0, y: 0, width: 10, height: 10}); - actor2 = new ex.Actor({x: 5, y: 5, width: 10, height: 10}); + actor1 = new ex.Actor({ x: 0, y: 0, width: 10, height: 10 }); + actor2 = new ex.Actor({ x: 5, y: 5, width: 10, height: 10 }); actor1.body.collisionType = ex.CollisionType.Active; actor2.body.collisionType = ex.CollisionType.Active; @@ -175,7 +175,7 @@ describe('A Collision', () => { it('should recognize when actor bodies are touching', () => { let touching = false; - actor1.on('postupdate', function() { + actor1.on('postupdate', function () { if (actor1.collider.get().touching(actor2.collider.get())) { touching = true; } @@ -189,12 +189,12 @@ describe('A Collision', () => { it('should not collide when active and passive', (done) => { ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; - const activeBlock = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const activeBlock = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; activeBlock.vel.x = 100; engine.add(activeBlock); - const passiveBlock = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); + const passiveBlock = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); passiveBlock.body.collisionType = ex.CollisionType.Passive; passiveBlock.vel.x = -100; engine.add(passiveBlock); @@ -221,12 +221,12 @@ describe('A Collision', () => { it('should emit a start collision once when objects start colliding', () => { ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; - const activeBlock = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const activeBlock = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; activeBlock.vel.x = 100; engine.add(activeBlock); - const passiveBlock = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); + const passiveBlock = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); passiveBlock.body.collisionType = ex.CollisionType.Passive; passiveBlock.vel.x = -100; engine.add(passiveBlock); @@ -247,12 +247,12 @@ describe('A Collision', () => { it('should emit a end collision once when objects stop colliding', () => { ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; - const activeBlock = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const activeBlock = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; activeBlock.vel.x = 100; engine.add(activeBlock); - const passiveBlock = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); + const passiveBlock = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); passiveBlock.body.collisionType = ex.CollisionType.Passive; passiveBlock.vel.x = -100; engine.add(passiveBlock); @@ -273,12 +273,12 @@ describe('A Collision', () => { it('should cancel out velocity when objects collide', () => { ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Arcade; engine.currentScene.clear(); - const activeBlock = new ex.Actor({name: 'active-block', x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const activeBlock = new ex.Actor({ name: 'active-block', x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; activeBlock.vel.x = 100; engine.add(activeBlock); - const fixedBlock = new ex.Actor({name: 'fixed-block', x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); + const fixedBlock = new ex.Actor({ name: 'fixed-block', x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); fixedBlock.body.collisionType = ex.CollisionType.Fixed; engine.add(fixedBlock); @@ -290,11 +290,11 @@ describe('A Collision', () => { it('should not cancel out velocity when objects move away', () => { ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Arcade; - const activeBlock = new ex.Actor({x: 350, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const activeBlock = new ex.Actor({ x: 350, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; engine.add(activeBlock); - const fixedBlock = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); + const fixedBlock = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); fixedBlock.body.collisionType = ex.CollisionType.Fixed; engine.add(fixedBlock); @@ -308,12 +308,12 @@ describe('A Collision', () => { it('should have the actor as the handler context for collisionstart', (done) => { ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; - const activeBlock = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const activeBlock = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; activeBlock.vel.x = 100; engine.add(activeBlock); - const passiveBlock = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); + const passiveBlock = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); passiveBlock.body.collisionType = ex.CollisionType.Passive; passiveBlock.vel.x = -100; engine.add(passiveBlock); @@ -331,12 +331,12 @@ describe('A Collision', () => { it('should have the actor as the handler context for collisionend', (done) => { ex.Physics.collisionResolutionStrategy = ex.SolverStrategy.Realistic; - const activeBlock = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const activeBlock = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); activeBlock.body.collisionType = ex.CollisionType.Active; activeBlock.vel.x = 100; engine.add(activeBlock); - const passiveBlock = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); + const passiveBlock = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); passiveBlock.body.collisionType = ex.CollisionType.Passive; passiveBlock.vel.x = -100; engine.add(passiveBlock); @@ -352,19 +352,15 @@ describe('A Collision', () => { }); it('should not fire onCollisionStart if the collision has been canceled', () => { - const block1 = new ex.Actor({x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone()}); + const block1 = new ex.Actor({ x: 200, y: 200, width: 50, height: 50, color: ex.Color.Red.clone() }); block1.body.collisionType = ex.CollisionType.Active; block1.vel.x = 100; - const block2 = new ex.Actor({x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone()}); - block2.collider.useCompositeCollider([ - ex.Shape.Box(50, 50), - ex.Shape.Box(50, 50) - ]); + const block2 = new ex.Actor({ x: 400, y: 200, width: 50, height: 50, color: ex.Color.DarkGray.clone() }); + block2.collider.useCompositeCollider([ex.Shape.Box(50, 50), ex.Shape.Box(50, 50)]); block2.body.collisionType = ex.CollisionType.Fixed; block2.vel.x = -100; - block1.onCollisionStart = jasmine.createSpy('onCollisionStart'); block2.onPreCollisionResolve = (self, other, side, contact) => { contact.cancel(); @@ -383,7 +379,7 @@ describe('A Collision', () => { it('should collisionend for a deleted collider', async () => { engine.stop(); engine.dispose(); - engine = TestUtils.engine({ width: 600, height: 400, physics: { enabled: true, solver: ex.SolverStrategy.Arcade }}); + engine = TestUtils.engine({ width: 600, height: 400, physics: { enabled: true, solver: ex.SolverStrategy.Arcade } }); clock = engine.clock = engine.clock.toTestClock(); await TestUtils.runToReady(engine); const activeBlock = new ex.Actor({ @@ -423,6 +419,5 @@ describe('A Collision', () => { clock.run(10, 100); expect(collisionEnd).toHaveBeenCalledTimes(1); - }); }); diff --git a/src/spec/ColorBlindCorrectorSpec.ts b/src/spec/ColorBlindCorrectorSpec.ts index 15fabd3d..0e7f732a 100644 --- a/src/spec/ColorBlindCorrectorSpec.ts +++ b/src/spec/ColorBlindCorrectorSpec.ts @@ -28,9 +28,11 @@ describe('A ColorBlindCorrector', () => { actor.graphics.use(bg.toSprite()); engine.add(actor); engine.once('postframe', (ev: ex.PostDrawEvent) => { - expectAsync(engine.canvas).toEqualImage('src/spec/images/ColorBlindCorrectorSpec/normal.png').then(() => { - done(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ColorBlindCorrectorSpec/normal.png') + .then(() => { + done(); + }); }); clock.step(1); }); @@ -41,9 +43,11 @@ describe('A ColorBlindCorrector', () => { engine.add(actor); engine.debug.colorBlindMode.correct(ex.ColorBlindnessMode.Deuteranope); engine.once('postframe', (ev: ex.PostDrawEvent) => { - expectAsync(engine.canvas).toEqualImage('src/spec/images/ColorBlindCorrectorSpec/deuteranope_correct.png').then(() => { - done(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ColorBlindCorrectorSpec/deuteranope_correct.png') + .then(() => { + done(); + }); }); clock.step(1); }); @@ -54,9 +58,11 @@ describe('A ColorBlindCorrector', () => { engine.add(actor); engine.debug.colorBlindMode.simulate(ex.ColorBlindnessMode.Deuteranope); engine.once('postframe', (ev: ex.PostDrawEvent) => { - expectAsync(engine.canvas).toEqualImage('src/spec/images/ColorBlindCorrectorSpec/deuteranope_simulate.png').then(() => { - done(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ColorBlindCorrectorSpec/deuteranope_simulate.png') + .then(() => { + done(); + }); }); clock.step(1); }); @@ -67,9 +73,11 @@ describe('A ColorBlindCorrector', () => { engine.add(actor); engine.debug.colorBlindMode.correct(ex.ColorBlindnessMode.Protanope); engine.once('postframe', (ev: ex.PostDrawEvent) => { - expectAsync(engine.canvas).toEqualImage('src/spec/images/ColorBlindCorrectorSpec/protanope_correct.png').then(() => { - done(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ColorBlindCorrectorSpec/protanope_correct.png') + .then(() => { + done(); + }); }); clock.step(1); }); @@ -80,9 +88,11 @@ describe('A ColorBlindCorrector', () => { engine.add(actor); engine.debug.colorBlindMode.simulate(ex.ColorBlindnessMode.Protanope); engine.once('postframe', (ev: ex.PostDrawEvent) => { - expectAsync(engine.canvas).toEqualImage('src/spec/images/ColorBlindCorrectorSpec/protanope_simulate.png').then(() => { - done(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ColorBlindCorrectorSpec/protanope_simulate.png') + .then(() => { + done(); + }); }); clock.step(1); }); @@ -93,9 +103,11 @@ describe('A ColorBlindCorrector', () => { engine.add(actor); engine.debug.colorBlindMode.correct(ex.ColorBlindnessMode.Tritanope); engine.once('postframe', (ev: ex.PostDrawEvent) => { - expectAsync(engine.canvas).toEqualImage('src/spec/images/ColorBlindCorrectorSpec/tritanope_correct.png').then(() => { - done(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ColorBlindCorrectorSpec/tritanope_correct.png') + .then(() => { + done(); + }); }); clock.step(1); }); @@ -106,9 +118,11 @@ describe('A ColorBlindCorrector', () => { engine.add(actor); engine.debug.colorBlindMode.simulate(ex.ColorBlindnessMode.Tritanope); engine.once('postframe', (ev: ex.PostDrawEvent) => { - expectAsync(engine.canvas).toEqualImage('src/spec/images/ColorBlindCorrectorSpec/tritanope_simulate.png').then(() => { - done(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ColorBlindCorrectorSpec/tritanope_simulate.png') + .then(() => { + done(); + }); }); clock.step(1); }); diff --git a/src/spec/ColorSpec.ts b/src/spec/ColorSpec.ts index 6c284853..5d6275bb 100644 --- a/src/spec/ColorSpec.ts +++ b/src/spec/ColorSpec.ts @@ -113,7 +113,7 @@ describe('A color', () => { expect(color.toHex()).toBe('#ffffff'); color = ex.Color.Green; expect(color.toHex()).toBe('#00ff00'); - color = ex.Color.fromRGB(17,17,17,0.1); + color = ex.Color.fromRGB(17, 17, 17, 0.1); expect(color.toHex()).toBe('#1111111a'); color = ex.Color.fromRGB(16.9, 16.9, 16.9); expect(color.toHex()).toBe('#111111'); diff --git a/src/spec/CompositeColliderSpec.ts b/src/spec/CompositeColliderSpec.ts index 5a847045..d64f40f2 100644 --- a/src/spec/CompositeColliderSpec.ts +++ b/src/spec/CompositeColliderSpec.ts @@ -30,10 +30,7 @@ describe('A CompositeCollider', () => { const collisionstart = jasmine.createSpy('event'); const collisionend = jasmine.createSpy('event'); - const compCollider = new ex.CompositeCollider([ - circle, - box - ]); + const compCollider = new ex.CompositeCollider([circle, box]); compCollider.events.on('precollision', precollision); compCollider.events.on('postcollision', postcollision); @@ -153,12 +150,11 @@ describe('A CompositeCollider', () => { const contactBoxCircle = compCollider.collide(circle); // Composite collisions have a special id that appends the "parent" id to the id to accurately track start/end expect(contactBoxCircle[0].id).toBe( - ex.Pair.calculatePairHash(compCollider.getColliders()[1].id, circle.id) + - '|' + - ex.Pair.calculatePairHash(compCollider.id, circle.id)); + ex.Pair.calculatePairHash(compCollider.getColliders()[1].id, circle.id) + '|' + ex.Pair.calculatePairHash(compCollider.id, circle.id) + ); }); - it('creates contacts that have the don\'t have composite collider id when in separate mode', () => { + it("creates contacts that have the don't have composite collider id when in separate mode", () => { const compCollider = new ex.CompositeCollider([ex.Shape.Circle(50), ex.Shape.Box(200, 10, Vector.Half)]); compCollider.compositeStrategy = 'separate'; @@ -171,8 +167,9 @@ describe('A CompositeCollider', () => { // Composite collisions have a special id that appends the "parent" id to the id to accurately track start/end expect(contactBoxCircle[0].id).toBe( ex.Pair.calculatePairHash(compCollider.getColliders()[1].id, circle.id) + - '|' + - ex.Pair.calculatePairHash(compCollider.getColliders()[1].id, circle.id)); + '|' + + ex.Pair.calculatePairHash(compCollider.getColliders()[1].id, circle.id) + ); }); it('can collide with other composite colliders', () => { @@ -320,8 +317,8 @@ describe('A CompositeCollider', () => { it('has the correct bounds when offset', () => { const compCollider = new ex.CompositeCollider([ex.Shape.Circle(50), ex.Shape.Box(200, 10, Vector.Half)]); - expect(compCollider.bounds).toEqual(new ex.BoundingBox({left: -100, right: 100, top: -50, bottom: 50})); + expect(compCollider.bounds).toEqual(new ex.BoundingBox({ left: -100, right: 100, top: -50, bottom: 50 })); compCollider.offset = ex.vec(50, 100); - expect(compCollider.bounds).toEqual(new ex.BoundingBox({left: -50, right: 150, top: 50, bottom: 150})); + expect(compCollider.bounds).toEqual(new ex.BoundingBox({ left: -50, right: 150, top: 50, bottom: 150 })); }); }); diff --git a/src/spec/ContextSpec.ts b/src/spec/ContextSpec.ts index 6a281353..d8893251 100644 --- a/src/spec/ContextSpec.ts +++ b/src/spec/ContextSpec.ts @@ -57,4 +57,4 @@ describe('A Context', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/src/spec/CoroutineSpec.ts b/src/spec/CoroutineSpec.ts index 76f423f1..9fbf9c42 100644 --- a/src/spec/CoroutineSpec.ts +++ b/src/spec/CoroutineSpec.ts @@ -35,7 +35,7 @@ describe('A Coroutine', () => { }); }).toThrowError( 'Cannot run coroutine without engine parameter outside of an excalibur lifecycle method.\n' + - 'Pass an engine parameter to ex.coroutine(engine, function * {...})' + 'Pass an engine parameter to ex.coroutine(engine, function * {...})' ); }); }); @@ -78,7 +78,6 @@ describe('A Coroutine', () => { }); }); - it('can run overload 2', async () => { const engine = TestUtils.engine({ width: 100, height: 100 }); await engine.scope(async () => { @@ -105,58 +104,69 @@ describe('A Coroutine', () => { const calls = jasmine.createSpy('calls'); - const preframe = ex.coroutine(function* () { - const elapsed = yield; - calls('preframe'); - expect(elapsed).toBe(100); - yield; - }, { timing: 'preframe' }); + const preframe = ex.coroutine( + function* () { + const elapsed = yield; + calls('preframe'); + expect(elapsed).toBe(100); + yield; + }, + { timing: 'preframe' } + ); - const postframe = ex.coroutine(function* () { - const elapsed = yield; - calls('postframe'); - expect(elapsed).toBe(100); - yield; - }, { timing: 'postframe' }); + const postframe = ex.coroutine( + function* () { + const elapsed = yield; + calls('postframe'); + expect(elapsed).toBe(100); + yield; + }, + { timing: 'postframe' } + ); - const preupdate = ex.coroutine(function* () { - const elapsed = yield; - calls('preupdate'); - expect(elapsed).toBe(100); - yield; - }, { timing: 'preupdate' }); + const preupdate = ex.coroutine( + function* () { + const elapsed = yield; + calls('preupdate'); + expect(elapsed).toBe(100); + yield; + }, + { timing: 'preupdate' } + ); - const postupdate = ex.coroutine(function* () { - const elapsed = yield; - calls('postupdate'); - expect(elapsed).toBe(100); - yield; - }, { timing: 'postupdate' }); + const postupdate = ex.coroutine( + function* () { + const elapsed = yield; + calls('postupdate'); + expect(elapsed).toBe(100); + yield; + }, + { timing: 'postupdate' } + ); - const predraw = ex.coroutine(function* () { - const elapsed = yield; - calls('predraw'); - expect(elapsed).toBe(100); - yield; - }, { timing: 'predraw' }); + const predraw = ex.coroutine( + function* () { + const elapsed = yield; + calls('predraw'); + expect(elapsed).toBe(100); + yield; + }, + { timing: 'predraw' } + ); - const postdraw = ex.coroutine(function* () { - const elapsed = yield; - calls('postdraw'); - expect(elapsed).toBe(100); - yield; - }, { timing: 'postdraw' }); + const postdraw = ex.coroutine( + function* () { + const elapsed = yield; + calls('postdraw'); + expect(elapsed).toBe(100); + yield; + }, + { timing: 'postdraw' } + ); clock.step(100); clock.step(100); - expect(calls.calls.allArgs()).toEqual([ - ['preframe'], - ['preupdate'], - ['postupdate'], - ['predraw'], - ['postdraw'], - ['postframe'] - ]); + expect(calls.calls.allArgs()).toEqual([['preframe'], ['preupdate'], ['postupdate'], ['predraw'], ['postdraw'], ['postframe']]); await expectAsync(preframe).toBeResolved(); await expectAsync(preupdate).toBeResolved(); await expectAsync(postupdate).toBeResolved(); @@ -167,7 +177,6 @@ describe('A Coroutine', () => { engine.dispose(); }); - it('can wait for given ms', async () => { const engine = TestUtils.engine({ width: 100, height: 100 }); const clock = engine.clock as ex.TestClock; @@ -177,7 +186,6 @@ describe('A Coroutine', () => { const elapsed = yield 200; expect(elapsed).toBe(200); yield; - }); // wait 200 ms clock.step(200); @@ -236,4 +244,4 @@ describe('A Coroutine', () => { engine.dispose(); }); }); -}); \ No newline at end of file +}); diff --git a/src/spec/CrossFadeSpec.ts b/src/spec/CrossFadeSpec.ts index ef776b8b..b4ad8a23 100644 --- a/src/spec/CrossFadeSpec.ts +++ b/src/spec/CrossFadeSpec.ts @@ -42,12 +42,14 @@ describe('A CrossFade transition', () => { const engine = TestUtils.engine({ backgroundColor: ex.Color.ExcaliburBlue }); const clock = engine.clock as ex.TestClock; await TestUtils.runToReady(engine); - engine.rootScene.add(new ex.Actor({ - pos: ex.vec(20, 20), - width: 100, - height: 100, - color: ex.Color.Red - })); + engine.rootScene.add( + new ex.Actor({ + pos: ex.vec(20, 20), + width: 100, + height: 100, + color: ex.Color.Red + }) + ); const onDeactivateSpy = jasmine.createSpy('onDeactivate').and.callFake(async () => { await Promise.resolve(); @@ -57,12 +59,14 @@ describe('A CrossFade transition', () => { const sut = new ex.CrossFade({ duration: 1000 }); const scene = new ex.Scene(); - scene.add(new ex.Actor({ - pos: ex.vec(200, 200), - width: 40, - height: 40, - color: ex.Color.Violet - })); + scene.add( + new ex.Actor({ + pos: ex.vec(200, 200), + width: 40, + height: 40, + color: ex.Color.Violet + }) + ); engine.addScene('newScene', { scene, transitions: { in: sut } }); const goto = engine.goto('newScene', { destinationIn: sut }); @@ -87,4 +91,4 @@ describe('A CrossFade transition', () => { expect(onDeactivateSpy).toHaveBeenCalledTimes(1); await expectAsync(engine.canvas).toEqualImage('/src/spec/images/CrossFadeSpec/crossfade.png'); }); -}); \ No newline at end of file +}); diff --git a/src/spec/DebugSpec.ts b/src/spec/DebugSpec.ts index 5ab98c91..3fc33279 100644 --- a/src/spec/DebugSpec.ts +++ b/src/spec/DebugSpec.ts @@ -27,7 +27,7 @@ describe('Debug draw static', () => { }); context.clear(); - ex.Debug.drawPoint(ex.vec(5, 5), {size: 5, color: ex.Color.ExcaliburBlue}); + ex.Debug.drawPoint(ex.vec(5, 5), { size: 5, color: ex.Color.ExcaliburBlue }); ex.Debug.flush(context); context.flush(); @@ -46,7 +46,7 @@ describe('Debug draw static', () => { }); context.clear(); - ex.Debug.drawLine(ex.vec(0, 0), ex.vec(10, 10), {color: ex.Color.ExcaliburBlue}); + ex.Debug.drawLine(ex.vec(0, 0), ex.vec(10, 10), { color: ex.Color.ExcaliburBlue }); ex.Debug.flush(context); context.flush(); @@ -65,7 +65,7 @@ describe('Debug draw static', () => { }); context.clear(); - ex.Debug.drawLines([ex.vec(0, 0), ex.vec(10, 10), ex.vec(10, 0), ex.vec(0, 10)], {color: ex.Color.ExcaliburBlue}); + ex.Debug.drawLines([ex.vec(0, 0), ex.vec(10, 10), ex.vec(10, 0), ex.vec(0, 10)], { color: ex.Color.ExcaliburBlue }); ex.Debug.flush(context); context.flush(); @@ -102,7 +102,7 @@ describe('Debug draw static', () => { }); context.clear(); - ex.Debug.drawPolygon([ex.vec(2, 2), ex.vec(8, 2), ex.vec(8, 8), ex.vec(2, 8)], {color: ex.Color.ExcaliburBlue}); + ex.Debug.drawPolygon([ex.vec(2, 2), ex.vec(8, 2), ex.vec(8, 8), ex.vec(2, 8)], { color: ex.Color.ExcaliburBlue }); ex.Debug.flush(context); context.flush(); @@ -121,7 +121,7 @@ describe('Debug draw static', () => { }); context.clear(); - ex.Debug.drawCircle(ex.vec(5, 5), 5, {color: ex.Color.Transparent, strokeColor: ex.Color.ExcaliburBlue, width: 1}); + ex.Debug.drawCircle(ex.vec(5, 5), 5, { color: ex.Color.Transparent, strokeColor: ex.Color.ExcaliburBlue, width: 1 }); ex.Debug.flush(context); context.flush(); @@ -176,4 +176,4 @@ describe('Debug draw static', () => { await expectAsync(canvas).toEqualImage('src/spec/images/DebugSpec/ray.png'); context.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/DebugSystemSpec.ts b/src/spec/DebugSystemSpec.ts index 882c013d..f74b3b02 100644 --- a/src/spec/DebugSystemSpec.ts +++ b/src/spec/DebugSystemSpec.ts @@ -202,15 +202,15 @@ describe('DebugSystem', () => { const entity = new ex.Entity([ new ex.TransformComponent(), - new ex.DebugGraphicsComponent(ctx => { + new ex.DebugGraphicsComponent((ctx) => { ctx.drawCircle(ex.vec(250, 250), 100, ex.Color.Blue); - })]); + }) + ]); debugSystem.query.checkAndAdd(entity); debugSystem.update(); engine.graphicsContext.flush(); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/DebugSystemSpec/debug-draw-component.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/DebugSystemSpec/debug-draw-component.png'); }); it('can debug draw a tilemap', async () => { diff --git a/src/spec/DebugTextSpec.ts b/src/spec/DebugTextSpec.ts index 89eb71c5..c1a799c4 100644 --- a/src/spec/DebugTextSpec.ts +++ b/src/spec/DebugTextSpec.ts @@ -45,6 +45,6 @@ describe('DebugText', () => { ctx.flush(); - await expectAsync(canvasElement).toEqualImage('src/spec/images/DebugTextSpec/draw-webgl.png', .94); + await expectAsync(canvasElement).toEqualImage('src/spec/images/DebugTextSpec/draw-webgl.png', 0.94); }); }); diff --git a/src/spec/DefaultLoaderSpec.ts b/src/spec/DefaultLoaderSpec.ts index 958a28f7..66b7335c 100644 --- a/src/spec/DefaultLoaderSpec.ts +++ b/src/spec/DefaultLoaderSpec.ts @@ -3,7 +3,6 @@ import { TestUtils } from './util/TestUtils'; import { ExcaliburAsyncMatchers, ExcaliburMatchers } from 'excalibur-jasmine'; describe('A DefaultLoader', () => { - let engine: ex.Engine; beforeEach(() => { jasmine.addMatchers(ExcaliburMatchers); @@ -37,7 +36,7 @@ describe('A DefaultLoader', () => { it('can draw', async () => { const sut = new ex.DefaultLoader({ - loadables: [ , , , ] + loadables: [, , ,] }); sut.onInitialize(engine); sut.markResourceComplete(); @@ -51,7 +50,7 @@ describe('A DefaultLoader', () => { const img1 = new ex.ImageSource('src/spec/images/DefaultLoaderSpec/loading.png'); const img2 = new ex.ImageSource('src/spec/images/DefaultLoaderSpec/loading.png'); const sut = new ex.DefaultLoader({ - loadables: [ img1, img2 ] + loadables: [img1, img2] }); sut.onInitialize(engine); @@ -75,4 +74,4 @@ describe('A DefaultLoader', () => { expect(resourceStartLoad).toHaveBeenCalledTimes(2); expect(resourceEndLoad).toHaveBeenCalledTimes(2); }); -}); \ No newline at end of file +}); diff --git a/src/spec/DirectorSpec.ts b/src/spec/DirectorSpec.ts index 45a104aa..f91422a8 100644 --- a/src/spec/DirectorSpec.ts +++ b/src/spec/DirectorSpec.ts @@ -57,8 +57,7 @@ describe('A Director', () => { }); sut.onInitialize(); - - const fadeIn = new ex.FadeInOut({ direction: 'in', duration: 1000}); + const fadeIn = new ex.FadeInOut({ direction: 'in', duration: 1000 }); const loader = new ex.DefaultLoader(); sut.configureStart('scene1', { inTransition: fadeIn, @@ -81,7 +80,7 @@ describe('A Director', () => { scene1, scene2 }); - const fadeIn = new ex.FadeInOut({ direction: 'in', duration: 1000}); + const fadeIn = new ex.FadeInOut({ direction: 'in', duration: 1000 }); const loader = new ex.DefaultLoader(); sut.configureStart('scene1', { inTransition: fadeIn, @@ -111,7 +110,7 @@ describe('A Director', () => { }); sut.rootScene._initialize(engine); engine.rootScene._initialize(engine); - const fadeIn = new ex.FadeInOut({ direction: 'in', duration: 1000}); + const fadeIn = new ex.FadeInOut({ direction: 'in', duration: 1000 }); engine.screen.setCurrentCamera(engine.currentScene.camera); fadeIn._initialize(engine); const loader = new ex.DefaultLoader(); @@ -253,4 +252,4 @@ describe('A Director', () => { expect(sut.currentScene).toBeInstanceOf(MyScene); engine.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/DynamicTreeBroadphaseSpec.ts b/src/spec/DynamicTreeBroadphaseSpec.ts index badc9449..ba34f02a 100644 --- a/src/spec/DynamicTreeBroadphaseSpec.ts +++ b/src/spec/DynamicTreeBroadphaseSpec.ts @@ -7,17 +7,17 @@ describe('A DynamicTree Broadphase', () => { let actorC: ex.Actor; beforeEach(() => { - actorA = new ex.Actor({x: 0, y: 0, width: 20, height: 20}); + actorA = new ex.Actor({ x: 0, y: 0, width: 20, height: 20 }); actorA.collider.useCircleCollider(10); actorA.body.collisionType = ex.CollisionType.Active; actorA.collider.update(); - actorB = new ex.Actor({x: 20, y: 0, width: 20, height: 20}); + actorB = new ex.Actor({ x: 20, y: 0, width: 20, height: 20 }); actorB.collider.useCircleCollider(10); actorB.body.collisionType = ex.CollisionType.Active; actorB.collider.update(); - actorC = new ex.Actor({x: 1000, y: 0, width: 20, height: 20}); + actorC = new ex.Actor({ x: 1000, y: 0, width: 20, height: 20 }); actorC.collider.useCircleCollider(10); actorC.body.collisionType = ex.CollisionType.Active; actorC.collider.update(); @@ -48,11 +48,8 @@ describe('A DynamicTree Broadphase', () => { it('should not find pairs for a composite collider', () => { const circle = ex.Shape.Circle(50); const box = ex.Shape.Box(200, 10); - const compCollider = new ex.CompositeCollider([ - circle, - box - ]); - const actor = new ex.Actor({collider: compCollider}); + const compCollider = new ex.CompositeCollider([circle, box]); + const actor = new ex.Actor({ collider: compCollider }); const dt = new ex.DynamicTreeCollisionProcessor(DefaultPhysicsConfig); dt.track(compCollider); @@ -63,11 +60,8 @@ describe('A DynamicTree Broadphase', () => { it('should not find pairs for a composite collider when moving fast', () => { const circle = ex.Shape.Circle(50); const box = ex.Shape.Box(200, 10); - const compCollider = new ex.CompositeCollider([ - circle, - box - ]); - const actor = new ex.Actor({collider: compCollider, collisionType: ex.CollisionType.Active}); + const compCollider = new ex.CompositeCollider([circle, box]); + const actor = new ex.Actor({ collider: compCollider, collisionType: ex.CollisionType.Active }); actor.body.vel = ex.vec(2000, 0); // extra fast to trigger the fast object detection const dt = new ex.DynamicTreeCollisionProcessor(DefaultPhysicsConfig); dt.track(compCollider); diff --git a/src/spec/EngineSpec.ts b/src/spec/EngineSpec.ts index be513d22..353eeb4f 100644 --- a/src/spec/EngineSpec.ts +++ b/src/spec/EngineSpec.ts @@ -76,11 +76,13 @@ describe('The engine', () => { loader.areResourcesLoaded().then(() => { testClock.run(2, 100); // 200 ms delay in loader expect(document.getElementById('excalibur-play')).withContext('Play button should exist in the document').toBeDefined(); - setTimeout(() => { // needed for the delay to work + setTimeout(() => { + // needed for the delay to work testClock.run(1, 100); engine.graphicsContext.flush(); expectAsync(engine.canvas) - .toEqualImage('src/spec/images/EngineSpec/engine-load-complete.png').then(() => { + .toEqualImage('src/spec/images/EngineSpec/engine-load-complete.png') + .then(() => { done(); }); }); @@ -106,7 +108,6 @@ describe('The engine', () => { engine = null; engine = TestUtils.engine(); - await engine.load(new FailedLoader()); expect(logger.error).toHaveBeenCalledWith('Error loading resources, things may not behave properly', new Error('I failed')); @@ -203,9 +204,12 @@ describe('The engine', () => { it('can flag on to the canvas fallback', async () => { engine.dispose(); engine = null; - engine = TestUtils.engine({ - suppressPlayButton: false - }, ['use-canvas-context']); + engine = TestUtils.engine( + { + suppressPlayButton: false + }, + ['use-canvas-context'] + ); await TestUtils.runToReady(engine); expect(engine.graphicsContext).toBeInstanceOf(ex.ExcaliburGraphicsContext2DCanvas); @@ -273,7 +277,8 @@ describe('The engine', () => { testClock.step(1); engine.graphicsContext.flush(); expectAsync(engine.canvas) - .toEqualImage('src/spec/images/EngineSpec/engine-suppress-play.png').then(() => { + .toEqualImage('src/spec/images/EngineSpec/engine-suppress-play.png') + .then(() => { done(); }); }); @@ -282,7 +287,7 @@ describe('The engine', () => { it('can set snapToPixel', () => { engine.dispose(); engine = null; - engine = TestUtils.engine({width: 100, height: 100}); + engine = TestUtils.engine({ width: 100, height: 100 }); expect(engine.snapToPixel).toBeFalse(); engine.snapToPixel = true; @@ -294,7 +299,7 @@ describe('The engine', () => { it('can set pixelRatio', () => { engine.dispose(); engine = null; - engine = TestUtils.engine({width: 100, height: 100, pixelRatio: 5, suppressHiDPIScaling: false}); + engine = TestUtils.engine({ width: 100, height: 100, pixelRatio: 5, suppressHiDPIScaling: false }); expect(engine.pixelRatio).toBe(5); expect(engine.screen.pixelRatio).toBe(5); expect(engine.screen.scaledWidth).toBe(500); @@ -304,12 +309,12 @@ describe('The engine', () => { it('can use draw sorting', () => { engine.dispose(); engine = null; - engine = TestUtils.engine({width: 100, height: 100, useDrawSorting: false}, []); + engine = TestUtils.engine({ width: 100, height: 100, useDrawSorting: false }, []); expect(engine.graphicsContext.useDrawSorting).toBe(false); engine.dispose(); engine = null; - engine = TestUtils.engine({width: 100, height: 100, useDrawSorting: true}, []); + engine = TestUtils.engine({ width: 100, height: 100, useDrawSorting: true }, []); expect(engine.graphicsContext.useDrawSorting).toBe(true); }); @@ -699,7 +704,6 @@ describe('The engine', () => { spyOn(scene1, 'onInitialize').and.callThrough(); spyOn(scene2, 'onInitialize').and.callThrough(); - await engine.goToScene('scene1'); await TestUtils.runToReady(engine); @@ -711,25 +715,28 @@ describe('The engine', () => { }); it('can screen shot the game (in WebGL)', (done) => { - const engine = TestUtils.engine({}, []); const clock = engine.clock as ex.TestClock; - engine.add(new ex.Actor({ - x: 50, - y: 50, - width: 100, - height: 100, - color: ex.Color.Red - })); + engine.add( + new ex.Actor({ + x: 50, + y: 50, + width: 100, + height: 100, + color: ex.Color.Red + }) + ); TestUtils.runToReady(engine).then(() => { clock.step(1); engine.screenshot().then((image) => { - expectAsync(image).toEqualImage(flushWebGLCanvasTo2D(engine.canvas)).then(() => { - done(); - engine.dispose(); - }); + expectAsync(image) + .toEqualImage(flushWebGLCanvasTo2D(engine.canvas)) + .then(() => { + done(); + engine.dispose(); + }); }); clock.step(1); clock.step(1); @@ -738,19 +745,20 @@ describe('The engine', () => { }); it('can screen shot the game HiDPI (in WebGL)', async () => { - const engine = TestUtils.engine({}, []); const clock = engine.clock as ex.TestClock; (engine.screen as any)._pixelRatioOverride = 2; engine.screen.applyResolutionAndViewport(); - engine.add(new ex.Actor({ - x: 50, - y: 50, - width: 100, - height: 100, - color: ex.Color.Red - })); + engine.add( + new ex.Actor({ + x: 50, + y: 50, + width: 100, + height: 100, + color: ex.Color.Red + }) + ); await TestUtils.runToReady(engine); clock.step(1); @@ -772,14 +780,17 @@ describe('The engine', () => { }); it('can screen shot and match the anti-aliasing with a half pixel when pixelRatio != 1.0', async () => { - const engine = TestUtils.engine({ - width: 200, - height: 200, - pixelRatio: 1.2, - suppressHiDPIScaling: false, - antialiasing: false, - snapToPixel: false - }, []); + const engine = TestUtils.engine( + { + width: 200, + height: 200, + pixelRatio: 1.2, + suppressHiDPIScaling: false, + antialiasing: false, + snapToPixel: false + }, + [] + ); const clock = engine.clock as ex.TestClock; const img = new ex.ImageSource('src/spec/images/EngineSpec/sprite.png'); await img.load(); @@ -834,7 +845,6 @@ describe('The engine', () => { await playerImage.load(); await backgroundImage.load(); - const tilemap = new ex.TileMap({ tileWidth: 16, tileHeight: 16, @@ -842,19 +852,19 @@ describe('The engine', () => { columns: 20, pos: ex.vec(0, 0) }); - tilemap.tiles.forEach(t => { + tilemap.tiles.forEach((t) => { t.addGraphic(backgroundSpriteSheet.getSprite(6, 0)); }); const player = new ex.Actor({ anchor: ex.vec(0, 0), - pos: ex.vec(16 * 8 + .9, 16 * 8 + .9) + pos: ex.vec(16 * 8 + 0.9, 16 * 8 + 0.9) }); player.graphics.use(playerSpriteSheet.getSprite(0, 0)); engine.add(tilemap); engine.add(player); - engine.currentScene.camera.pos = player.pos.add(ex.vec(.05, .05)); + engine.currentScene.camera.pos = player.pos.add(ex.vec(0.05, 0.05)); clock.step(); @@ -902,7 +912,6 @@ describe('The engine', () => { await playerImage.load(); await backgroundImage.load(); - const tilemap = new ex.TileMap({ tileWidth: 16, tileHeight: 16, @@ -910,7 +919,7 @@ describe('The engine', () => { columns: 20, pos: ex.vec(0, 0) }); - tilemap.tiles.forEach(t => { + tilemap.tiles.forEach((t) => { t.addGraphic(backgroundSpriteSheet.getSprite(6, 0)); }); diff --git a/src/spec/EntitySpec.ts b/src/spec/EntitySpec.ts index 1a6981e0..731f31d4 100644 --- a/src/spec/EntitySpec.ts +++ b/src/spec/EntitySpec.ts @@ -12,7 +12,7 @@ describe('An entity', () => { }); it('can be constructed with a list of components', () => { - const e = new ex.Entity([new FakeComponentA, new FakeComponentB, new FakeComponentC]); + const e = new ex.Entity([new FakeComponentA(), new FakeComponentB(), new FakeComponentC()]); expect(e.has(FakeComponentA)).toBe(true); expect(e.has(FakeComponentB)).toBe(true); @@ -20,11 +20,11 @@ describe('An entity', () => { }); it('can override existing components', () => { - const original = new FakeComponentA; + const original = new FakeComponentA(); const e = new ex.Entity([original]); spyOn(e, 'removeComponent'); - const newComponent = new FakeComponentA; + const newComponent = new FakeComponentA(); e.addComponent(newComponent, true); expect(e.removeComponent).toHaveBeenCalledWith(FakeComponentA, true); }); @@ -63,14 +63,14 @@ describe('An entity', () => { it('can have types by component', () => { const entity = new ex.Entity(); - const typeA = new FakeComponentA; - const typeB = new FakeComponentB; + const typeA = new FakeComponentA(); + const typeB = new FakeComponentB(); expect(entity.types).toEqual([]); entity.addComponent(typeA); expect(entity.types).toEqual([FakeComponentA]); entity.addComponent(typeB); - expect(entity.types).toEqual([ FakeComponentA, FakeComponentB]); + expect(entity.types).toEqual([FakeComponentA, FakeComponentB]); entity.removeComponent(FakeComponentA, true); expect(entity.types).toEqual([FakeComponentB]); entity.removeComponent(FakeComponentB, true); @@ -79,9 +79,9 @@ describe('An entity', () => { it('can get a list of components', () => { const entity = new ex.Entity(); - const typeA = new FakeComponentA; - const typeB = new FakeComponentB; - const typeC = new FakeComponentC; + const typeA = new FakeComponentA(); + const typeB = new FakeComponentB(); + const typeC = new FakeComponentC(); expect(entity.getComponents()).toEqual([]); @@ -93,7 +93,7 @@ describe('An entity', () => { it('can have type from tag components', () => { const entity = new ex.Entity(); // const isOffscreen = new TagComponent('offscreen'); - const nonTag = new FakeComponentA; + const nonTag = new FakeComponentA(); expect(entity.types).toEqual([]); entity.addTag('offscreen'); @@ -120,7 +120,7 @@ describe('An entity', () => { it('can be observed for added changes', (done) => { const entity = new ex.Entity(); - const typeA = new FakeComponentA; + const typeA = new FakeComponentA(); entity.componentAdded$.register({ notify: (change) => { expect(change.owner).toBe(entity); @@ -133,7 +133,7 @@ describe('An entity', () => { it('can be observed for removed changes', (done) => { const entity = new ex.Entity(); - const typeA = new FakeComponentA; + const typeA = new FakeComponentA(); entity.addComponent(typeA); entity.componentRemoved$.register({ @@ -149,11 +149,11 @@ describe('An entity', () => { it('can be cloned', () => { const entity = new ex.Entity(); - const typeA = new FakeComponentA; - const typeB = new FakeComponentB; + const typeA = new FakeComponentA(); + const typeB = new FakeComponentB(); entity.addComponent(typeA); entity.addComponent(typeB); - entity.addChild(new ex.Entity([new FakeComponentZ])); + entity.addChild(new ex.Entity([new FakeComponentZ()])); const clone = entity.clone(); expect(clone).not.toBe(entity); @@ -168,8 +168,8 @@ describe('An entity', () => { it('can be initialized with a template', () => { const entity = new ex.Entity(); - const template = new ex.Entity([new FakeComponentA, new FakeComponentB]).addChild( - new ex.Entity([new FakeComponentC, new FakeComponentD]).addChild(new ex.Entity([new FakeComponentZ])) + const template = new ex.Entity([new FakeComponentA(), new FakeComponentB()]).addChild( + new ex.Entity([new FakeComponentC(), new FakeComponentD()]).addChild(new ex.Entity([new FakeComponentZ()])) ); expect(entity.getComponents()).toEqual([]); @@ -181,8 +181,8 @@ describe('An entity', () => { it('can be checked if it has a component', () => { const entity = new ex.Entity(); - const typeA = new FakeComponentA; - const typeB = new FakeComponentB; + const typeA = new FakeComponentA(); + const typeB = new FakeComponentB(); entity.addComponent(typeA); entity.addComponent(typeB); @@ -282,7 +282,7 @@ describe('An entity', () => { expect(child.parent).toBe(null); }); - it('can\'t have a cycle', () => { + it("can't have a cycle", () => { const parent = new ex.Entity(); const child = new ex.Entity(); @@ -293,7 +293,7 @@ describe('An entity', () => { }).toThrowError('Cycle detected, cannot add entity'); }); - it('can\'t parent if already parented', () => { + it("can't parent if already parented", () => { const parent = new ex.Entity(); const child = new ex.Entity(); const otherParent = new ex.Entity(); @@ -310,7 +310,7 @@ describe('An entity', () => { e.componentAdded$.register({ notify: addedSpy }); - const component = new FakeComponentA; + const component = new FakeComponentA(); e.addComponent(component); expect(addedSpy).toHaveBeenCalledTimes(1); }); @@ -321,7 +321,7 @@ describe('An entity', () => { e.componentRemoved$.register({ notify: removedSpy }); - const component = new FakeComponentA; + const component = new FakeComponentA(); e.addComponent(component); e.removeComponent(FakeComponentA); e.processComponentRemoval(); @@ -486,7 +486,7 @@ describe('An entity', () => { it('will return subclass instances of types', () => { class MyBody extends ex.BodyComponent {} - const body = new MyBody; + const body = new MyBody(); const sut = new ex.Entity([body]); expect(sut.get(MyBody)).toBe(body); @@ -494,7 +494,7 @@ describe('An entity', () => { sut.removeComponent(body, true); - const superBody = new ex.BodyComponent; + const superBody = new ex.BodyComponent(); sut.addComponent(superBody); expect(sut.get(MyBody)).toBe(undefined); expect(sut.get(ex.BodyComponent)).toBe(superBody); diff --git a/src/spec/EventEmitterSpec.ts b/src/spec/EventEmitterSpec.ts index f95adb4b..a989cd66 100644 --- a/src/spec/EventEmitterSpec.ts +++ b/src/spec/EventEmitterSpec.ts @@ -142,7 +142,7 @@ describe('An EventEmitter', () => { it('can unpipe from other emitters', () => { const pubSub = new ex.EventEmitter(); - const newPubSub = new ex.EventEmitter<{someevent: number, otherevent: number}>(); + const newPubSub = new ex.EventEmitter<{ someevent: number; otherevent: number }>(); newPubSub.pipe(pubSub); const handler = jasmine.createSpy('handler'); @@ -162,7 +162,7 @@ describe('An EventEmitter', () => { it('can unpipe from other emitters via subscription.close()', () => { const pubSub = new ex.EventEmitter(); - const newPubSub = new ex.EventEmitter<{someevent: number, otherevent: number}>(); + const newPubSub = new ex.EventEmitter<{ someevent: number; otherevent: number }>(); const sub = newPubSub.pipe(pubSub); const handler = jasmine.createSpy('handler'); @@ -285,4 +285,4 @@ describe('An EventEmitter', () => { pubsub.emit('event', null); expect(eventHistory).toEqual(subscriptions); }); -}); \ No newline at end of file +}); diff --git a/src/spec/EventSpec.ts b/src/spec/EventSpec.ts index ce789a5d..62e63bbb 100644 --- a/src/spec/EventSpec.ts +++ b/src/spec/EventSpec.ts @@ -16,7 +16,7 @@ describe('An Event Dispatcher', () => { it('can publish events', () => { let eventFired = false; - pubsub.on('event', function() { + pubsub.on('event', function () { eventFired = true; }); pubsub.emit('event', null); @@ -28,7 +28,7 @@ describe('An Event Dispatcher', () => { const target = new ex.Actor(); pubsub = new ex.EventDispatcher(); - pubsub.on('event', function() { + pubsub.on('event', function () { targetContext = this; }); pubsub.emit('event', null); @@ -37,7 +37,7 @@ describe('An Event Dispatcher', () => { it('has an emit alias for publish', () => { let eventFired = false; - pubsub.on('event', function() { + pubsub.on('event', function () { eventFired = true; }); pubsub.emit('event', null); diff --git a/src/spec/ExcaliburGraphicsContextSpec.ts b/src/spec/ExcaliburGraphicsContextSpec.ts index aa9d2d98..831b5c69 100644 --- a/src/spec/ExcaliburGraphicsContextSpec.ts +++ b/src/spec/ExcaliburGraphicsContextSpec.ts @@ -2,8 +2,6 @@ import * as ex from '@excalibur'; import { TextureLoader } from '@excalibur'; import { ExcaliburAsyncMatchers, ExcaliburMatchers } from 'excalibur-jasmine'; - - describe('The ExcaliburGraphicsContext', () => { describe('2D', () => { let testCanvasElement: HTMLCanvasElement; @@ -326,7 +324,7 @@ describe('The ExcaliburGraphicsContext', () => { }); context.clear(); - rect.draw(context, .5, .5);//1 - 0.001, 1 - 0.001); + rect.draw(context, 0.5, 0.5); //1 - 0.001, 1 - 0.001); context.flush(); await expectAsync(canvas).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap.png'); @@ -355,9 +353,7 @@ describe('The ExcaliburGraphicsContext', () => { rect.draw(context, 1 - 0.0001, 1 - 0.0001); context.flush(); - await expectAsync(canvas).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-next.png' - ); + await expectAsync(canvas).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-next.png'); context.dispose(); }); @@ -378,9 +374,7 @@ describe('The ExcaliburGraphicsContext', () => { context.drawRectangle(ex.vec(1 - 0.0001, 1 - 0.0001), 2, 2, ex.Color.Red); context.flush(); - await expectAsync(canvas).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-next.png' - ); + await expectAsync(canvas).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-next.png'); context.dispose(); }); @@ -401,9 +395,7 @@ describe('The ExcaliburGraphicsContext', () => { context.drawLine(ex.vec(1 - 0.0001, 2 - 0.0001), ex.vec(5, 2 - 0.0001), ex.Color.Red, 2); context.flush(); - await expectAsync(canvas).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-line-next.png' - ); + await expectAsync(canvas).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-line-next.png'); context.dispose(); }); @@ -424,9 +416,7 @@ describe('The ExcaliburGraphicsContext', () => { context.drawCircle(ex.vec(5 - 0.0001, 5 - 0.0001), 3, ex.Color.Red); context.flush(); - await expectAsync(canvas).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-circle-next.png' - ); + await expectAsync(canvas).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-circle-next.png'); context.dispose(); }); @@ -450,9 +440,7 @@ describe('The ExcaliburGraphicsContext', () => { }); context.flush(); - await expectAsync(canvas).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-point-next.png' - ); + await expectAsync(canvas).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/pixel-snap-point-next.png'); context.dispose(); }); @@ -477,9 +465,7 @@ describe('The ExcaliburGraphicsContext', () => { sut.drawImage(rect._bitmap, 20, 20); sut.flush(); - await expectAsync(canvasElement).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/2d-drawgraphic.png' - ); + await expectAsync(canvasElement).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/2d-drawgraphic.png'); sut.dispose(); }); @@ -501,9 +487,7 @@ describe('The ExcaliburGraphicsContext', () => { }); sut.flush(); - await expectAsync(canvasElement).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/webgl-drawpoint.png' - ); + await expectAsync(canvasElement).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/webgl-drawpoint.png'); sut.dispose(); }); @@ -524,8 +508,9 @@ describe('The ExcaliburGraphicsContext', () => { sut.drawCircle(ex.vec(0, 0), 10, ex.Color.Blue); expect(logger.warnOnce).toHaveBeenCalledWith( - `Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\n`+ - `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`); + `Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\n` + + `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.` + ); sut.dispose(); }); @@ -601,7 +586,7 @@ describe('The ExcaliburGraphicsContext', () => { await expectAsync(canvasElement).toEqualImage( 'src/spec/images/ExcaliburGraphicsContextSpec/painter-order-circle-image-rect.png', - .97 + 0.97 ); sut.dispose(); }); @@ -654,7 +639,7 @@ describe('The ExcaliburGraphicsContext', () => { await expectAsync(canvasElement).toEqualImage( 'src/spec/images/ExcaliburGraphicsContextSpec/painter-order-circle-image-rect.png', - .97 + 0.97 ); sut.dispose(); }); @@ -678,9 +663,7 @@ describe('The ExcaliburGraphicsContext', () => { }); sut.flush(); - await expectAsync(canvasElement).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/webgl-drawline.png' - ); + await expectAsync(canvasElement).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/webgl-drawline.png'); sut.dispose(); }); @@ -722,9 +705,7 @@ describe('The ExcaliburGraphicsContext', () => { sut.drawRectangle(ex.vec(10, 10), 80, 80, ex.Color.Blue); sut.flush(); - await expectAsync(canvasElement).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/webgl-solid-rect.png' - ); + await expectAsync(canvasElement).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/webgl-solid-rect.png'); sut.dispose(); }); @@ -763,8 +744,7 @@ describe('The ExcaliburGraphicsContext', () => { sut.drawCircle(ex.vec(50, 50), 50, ex.Color.Blue); sut.flush(); - await expectAsync(canvasElement).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/webgl-circle-with-opacity.png'); + await expectAsync(canvasElement).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/webgl-circle-with-opacity.png'); sut.dispose(); }); @@ -1010,9 +990,7 @@ describe('The ExcaliburGraphicsContext', () => { sut.restore(); sut.flush(); - await expectAsync(canvasElement).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/webgl-transform.png' - ); + await expectAsync(canvasElement).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/webgl-transform.png'); sut.dispose(); }); @@ -1038,9 +1016,7 @@ describe('The ExcaliburGraphicsContext', () => { sut.drawImage(rect._bitmap, 1.9, 1.9); sut.flush(); - await expectAsync(canvasElement).toEqualImage( - 'src/spec/images/ExcaliburGraphicsContextSpec/2d-snap-to-pixel.png' - ); + await expectAsync(canvasElement).toEqualImage('src/spec/images/ExcaliburGraphicsContextSpec/2d-snap-to-pixel.png'); sut.dispose(); }); diff --git a/src/spec/FadeInOutSpec.ts b/src/spec/FadeInOutSpec.ts index 40232beb..2eda12ec 100644 --- a/src/spec/FadeInOutSpec.ts +++ b/src/spec/FadeInOutSpec.ts @@ -21,12 +21,14 @@ describe('A FadeInOut transition', () => { const engine = TestUtils.engine({ backgroundColor: ex.Color.ExcaliburBlue }); const clock = engine.clock as ex.TestClock; await TestUtils.runToReady(engine); - engine.add(new ex.Actor({ - pos: ex.vec(20, 20), - width: 100, - height: 100, - color: ex.Color.Red - })); + engine.add( + new ex.Actor({ + pos: ex.vec(20, 20), + width: 100, + height: 100, + color: ex.Color.Red + }) + ); const onDeactivateSpy = jasmine.createSpy('onDeactivate').and.callFake(async () => { await Promise.resolve(); @@ -36,12 +38,14 @@ describe('A FadeInOut transition', () => { const sut = new ex.FadeInOut({ duration: 1000, direction: 'in' }); const scene = new ex.Scene(); - scene.add(new ex.Actor({ - pos: ex.vec(200, 200), - width: 40, - height: 40, - color: ex.Color.Violet - })); + scene.add( + new ex.Actor({ + pos: ex.vec(200, 200), + width: 40, + height: 40, + color: ex.Color.Violet + }) + ); engine.addScene('newScene', { scene, transitions: { in: sut } }); const goto = engine.goto('newScene'); @@ -57,22 +61,25 @@ describe('A FadeInOut transition', () => { const engine = TestUtils.engine({ backgroundColor: ex.Color.ExcaliburBlue }); const clock = engine.clock as ex.TestClock; await TestUtils.runToReady(engine); - engine.add(new ex.Actor({ - pos: ex.vec(20, 20), - width: 100, - height: 100, - color: ex.Color.Red - })); - + engine.add( + new ex.Actor({ + pos: ex.vec(20, 20), + width: 100, + height: 100, + color: ex.Color.Red + }) + ); const sut = new ex.FadeInOut({ duration: 1000, direction: 'out', color: ex.Color.Violet }); const scene = new ex.Scene(); - scene.add(new ex.Actor({ - pos: ex.vec(200, 200), - width: 40, - height: 40, - color: ex.Color.Violet - })); + scene.add( + new ex.Actor({ + pos: ex.vec(200, 200), + width: 40, + height: 40, + color: ex.Color.Violet + }) + ); engine.addScene('newScene', scene); const goto = engine.goToScene('newScene', { sourceOut: sut }); @@ -82,4 +89,4 @@ describe('A FadeInOut transition', () => { await expectAsync(engine.canvas).toEqualImage('/src/spec/images/FadeInOutSpec/fadeout.png'); engine.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/FlagsSpec.ts b/src/spec/FlagsSpec.ts index 7232b6ed..5a66e782 100644 --- a/src/spec/FlagsSpec.ts +++ b/src/spec/FlagsSpec.ts @@ -18,13 +18,7 @@ describe('Feature Flags', () => { ex.Flags.enable('some-flag-3'); ex.Flags.disable('some-flag-4'); ex.Flags.enable('some-flag-5'); - expect(ex.Flags.show()).toEqual([ - 'some-flag-1', - 'some-flag-2', - 'some-flag-3', - 'some-flag-4', - 'some-flag-5' - ]); + expect(ex.Flags.show()).toEqual(['some-flag-1', 'some-flag-2', 'some-flag-3', 'some-flag-4', 'some-flag-5']); }); it('should let you set flags', () => { @@ -33,7 +27,7 @@ describe('Feature Flags', () => { expect(ex.Flags.isEnabled('some-flag')).toBeTrue(); }); - it('should let you disable flags',( ) => { + it('should let you disable flags', () => { ex.Flags.disable('some-other-flag'); expect(ex.Flags.isEnabled('some-other-flag')).toBeFalse(); @@ -71,12 +65,11 @@ describe('Feature Flags', () => { ex.Flags.disable('some-flag'); }).not.toThrow(); - const engine = new ex.Engine({ suppressConsoleBootMessage: true}); + const engine = new ex.Engine({ suppressConsoleBootMessage: true }); expect(() => { ex.Flags.disable('some-flag'); }).toThrow(); engine.dispose(); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/FontSourceSpec.ts b/src/spec/FontSourceSpec.ts index 694e3192..cc0f3415 100644 --- a/src/spec/FontSourceSpec.ts +++ b/src/spec/FontSourceSpec.ts @@ -76,11 +76,9 @@ describe('A FontSource', () => { expect(font).toBe(alreadyLoadedFont); }); - it('will return error if font doesn\'t exist', async () => { + it("will return error if font doesn't exist", async () => { const fontSource = new ex.FontSource('42.ttf', '42'); - await expectAsync(fontSource.load()).toBeRejectedWith( - 'Error loading FontSource from path \'42.ttf\' with error [Not Found]' - ); + await expectAsync(fontSource.load()).toBeRejectedWith("Error loading FontSource from path '42.ttf' with error [Not Found]"); }); }); diff --git a/src/spec/FutureSpec.ts b/src/spec/FutureSpec.ts index 53bcd5c8..8ac52c31 100644 --- a/src/spec/FutureSpec.ts +++ b/src/spec/FutureSpec.ts @@ -70,4 +70,4 @@ describe('A Future', () => { future.reject(new Error('Some error')); }).not.toThrow(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/GamepadSpec.ts b/src/spec/GamepadSpec.ts index 4461e1c6..f55e1f01 100644 --- a/src/spec/GamepadSpec.ts +++ b/src/spec/GamepadSpec.ts @@ -13,7 +13,7 @@ describe('A gamepad', () => { nav = mock.navigator(); - spyOn(navigator, 'getGamepads').and.callFake(function(): any[] { + spyOn(navigator, 'getGamepads').and.callFake(function (): any[] { return nav.getGamepads(); }); }); diff --git a/src/spec/GraphicsComponentSpec.ts b/src/spec/GraphicsComponentSpec.ts index b20d97fe..baaee378 100644 --- a/src/spec/GraphicsComponentSpec.ts +++ b/src/spec/GraphicsComponentSpec.ts @@ -37,11 +37,15 @@ describe('A Graphics ECS Component', () => { }); graphics.anchor = ex.vec(0, 0); graphics.offset = ex.vec(1, 1); - graphics.opacity = .2; + graphics.opacity = 0.2; graphics.visible = false; graphics.copyGraphics = true; - graphics.onPreDraw = () => { /* do nothing */ }; - graphics.onPostDraw = () => { /* do nothing */}; + graphics.onPreDraw = () => { + /* do nothing */ + }; + graphics.onPostDraw = () => { + /* do nothing */ + }; graphics.use(rect); const clone = owner.clone(); @@ -271,7 +275,6 @@ describe('A Graphics ECS Component', () => { expect(animation.tick).toHaveBeenCalledWith(123, 4); }); - it('correctly calculates graphics bounds (rasters)', () => { const sut = new ex.GraphicsComponent(); const rec2 = new ex.Rectangle({ @@ -281,12 +284,14 @@ describe('A Graphics ECS Component', () => { rec2.scale = ex.vec(2, 2); sut.add(rec2); - expect(sut.localBounds).toEqual(new ex.BoundingBox({ - left: -200, - right: 200, - top: -10, - bottom: 10 - })); + expect(sut.localBounds).toEqual( + new ex.BoundingBox({ + left: -200, + right: 200, + top: -10, + bottom: 10 + }) + ); }); it('correctly calculates graphics world bounds (rasters)', () => { @@ -302,12 +307,14 @@ describe('A Graphics ECS Component', () => { const entity = new ex.Entity([tx, sut]); - expect(sut.bounds).toEqual(new ex.BoundingBox({ - left: 300, - right: 700, - top: 890, - bottom: 910 - })); + expect(sut.bounds).toEqual( + new ex.BoundingBox({ + left: 300, + right: 700, + top: 890, + bottom: 910 + }) + ); }); it('correctly calculates graphics bounds (rasters + offset)', () => { @@ -317,14 +324,16 @@ describe('A Graphics ECS Component', () => { height: 10 }); rec2.scale = ex.vec(2, 2); // width 400, height 20 - sut.use(rec2, { offset: ex.vec(100, 0)}); // offset 100 to the right - - expect(sut.localBounds).toEqual(new ex.BoundingBox({ - left: -100, - right: 300, - top: -10, - bottom: 10 - })); + sut.use(rec2, { offset: ex.vec(100, 0) }); // offset 100 to the right + + expect(sut.localBounds).toEqual( + new ex.BoundingBox({ + left: -100, + right: 300, + top: -10, + bottom: 10 + }) + ); }); it('correctly calculates graphics bounds (rasters + anchor)', () => { @@ -334,14 +343,16 @@ describe('A Graphics ECS Component', () => { height: 10 }); rec2.scale = ex.vec(2, 2); // width 400, height 20 - sut.use(rec2, { anchor: ex.vec(1, 1)}); // anchor at the bottom right - - expect(sut.localBounds).toEqual(new ex.BoundingBox({ - left: -400, - right: 0, - top: -20, - bottom: 0 - })); + sut.use(rec2, { anchor: ex.vec(1, 1) }); // anchor at the bottom right + + expect(sut.localBounds).toEqual( + new ex.BoundingBox({ + left: -400, + right: 0, + top: -20, + bottom: 0 + }) + ); }); it('correctly calculates graphics bounds (sprite)', () => { @@ -363,12 +374,14 @@ describe('A Graphics ECS Component', () => { sprite.scale = ex.vec(4, 4); sut.add(sprite); - expect(sut.localBounds).toEqual(new ex.BoundingBox({ - left: -200, - right: 200, - top: -200, - bottom: 200 - })); + expect(sut.localBounds).toEqual( + new ex.BoundingBox({ + left: -200, + right: 200, + top: -200, + bottom: 200 + }) + ); }); it('correctly calculates graphics bounds (animation)', () => { @@ -388,11 +401,13 @@ describe('A Graphics ECS Component', () => { anim.scale = ex.vec(4, 4); sut.add(anim); - expect(sut.localBounds).toEqual(new ex.BoundingBox({ - left: -20, - right: 20, - top: -20, - bottom: 20 - })); + expect(sut.localBounds).toEqual( + new ex.BoundingBox({ + left: -20, + right: 20, + top: -20, + bottom: 20 + }) + ); }); }); diff --git a/src/spec/GraphicsSystemSpec.ts b/src/spec/GraphicsSystemSpec.ts index eea3bfcf..54474196 100644 --- a/src/spec/GraphicsSystemSpec.ts +++ b/src/spec/GraphicsSystemSpec.ts @@ -38,9 +38,9 @@ describe('A Graphics ECS System', () => { engine.currentScene._initialize(engine); sut.initialize(world, engine.currentScene); const es = [...entities]; - es.forEach(e => sut.query.entityAdded$.notifyAll(e)); + es.forEach((e) => sut.query.entityAdded$.notifyAll(e)); sut.preupdate(); - expect(sut.sortedTransforms.map(t => t.owner)).toEqual(entities.reverse()); + expect(sut.sortedTransforms.map((t) => t.owner)).toEqual(entities.reverse()); }); it('draws entities with transform and graphics components', async () => { @@ -93,8 +93,8 @@ describe('A Graphics ECS System', () => { entities.push(offscreen); engine.graphicsContext.clear(); - entities.forEach(e => offscreenSystem.query.checkAndAdd(e)); - entities.forEach(e => sut.query.checkAndAdd(e)); + entities.forEach((e) => offscreenSystem.query.checkAndAdd(e)); + entities.forEach((e) => sut.query.checkAndAdd(e)); offscreenSystem.update(); @@ -173,7 +173,7 @@ describe('A Graphics ECS System', () => { graphicsSystem.preupdate(); graphicsSystem.query.checkAndAdd(actor); - game.currentFrameLagMs = (1000 / 30) / 2; // current lag in a 30 fps frame + game.currentFrameLagMs = 1000 / 30 / 2; // current lag in a 30 fps frame graphicsSystem.update(16); expect(translateSpy.calls.argsFor(0)).toEqual([10, 10]); @@ -224,9 +224,7 @@ describe('A Graphics ECS System', () => { offscreenSystem.initialize(world, engine.currentScene); sut.initialize(world, engine.currentScene); - - - engine.graphicsContext.opacity = .5; + engine.graphicsContext.opacity = 0.5; const actor = new ex.Actor({ x: 10, @@ -235,7 +233,7 @@ describe('A Graphics ECS System', () => { width: 10, color: ex.Color.Red }); - actor.graphics.opacity = .5; + actor.graphics.opacity = 0.5; sut.query.checkAndAdd(actor); @@ -247,8 +245,7 @@ describe('A Graphics ECS System', () => { sut.update(1); engine.graphicsContext.flush(); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/GraphicsSystemSpec/graphics-context-opacity.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/GraphicsSystemSpec/graphics-context-opacity.png'); }); it('can flip graphics horizontally', async () => { @@ -282,8 +279,7 @@ describe('A Graphics ECS System', () => { sut.update(1); engine.graphicsContext.flush(); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-horizontal.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-horizontal.png'); }); it('can flip graphics vertically', async () => { @@ -317,8 +313,7 @@ describe('A Graphics ECS System', () => { sut.update(1); engine.graphicsContext.flush(); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-vertical.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-vertical.png'); }); it('can flip graphics both horizontally and vertically', async () => { @@ -353,8 +348,7 @@ describe('A Graphics ECS System', () => { sut.update(1); engine.graphicsContext.flush(); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-both.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-both.png'); }); it('can flip graphics both horizontally and vertically with an offset', async () => { @@ -390,7 +384,6 @@ describe('A Graphics ECS System', () => { sut.update(1); engine.graphicsContext.flush(); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-both-offset.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/GraphicsSystemSpec/sword-flip-both-offset.png'); }); }); diff --git a/src/spec/ImageSourceSpec.ts b/src/spec/ImageSourceSpec.ts index 000edaac..74b25ca8 100644 --- a/src/spec/ImageSourceSpec.ts +++ b/src/spec/ImageSourceSpec.ts @@ -47,10 +47,12 @@ describe('A ImageSource', () => { await sut.load(); - expect(logger.warn).toHaveBeenCalledWith( `The image [src/spec/images/GraphicsImageSourceSpec/big-image.png] provided to excalibur` + - ` is too large may not work on all mobile devices, it is recommended you resize images to a maximum (4096x4096).\n\n` + - `Images will likely render as black rectangles on some mobile platforms.\n\n` + - `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`); + expect(logger.warn).toHaveBeenCalledWith( + `The image [src/spec/images/GraphicsImageSourceSpec/big-image.png] provided to excalibur` + + ` is too large may not work on all mobile devices, it is recommended you resize images to a maximum (4096x4096).\n\n` + + `Images will likely render as black rectangles on some mobile platforms.\n\n` + + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits` + ); expect(logger.error).not.toHaveBeenCalled(); }); @@ -76,9 +78,10 @@ describe('A ImageSource', () => { expect(logger.warn).not.toHaveBeenCalled(); expect(logger.error).toHaveBeenCalledWith( `The image [src/spec/images/GraphicsImageSourceSpec/big-image.png] provided to Excalibur is too large for the device's maximum ` + - `texture size of (4096x4096) please resize to an image for excalibur to render properly.\n\n` + - `Images will likely render as black rectangles.\n\n` + - `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`); + `texture size of (4096x4096) please resize to an image for excalibur to render properly.\n\n` + + `Images will likely render as black rectangles.\n\n` + + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits` + ); }); it('can load images with an image filtering Blended', async () => { @@ -86,7 +89,7 @@ describe('A ImageSource', () => { const webgl = new ex.ExcaliburGraphicsContextWebGL({ canvasElement: canvas }); - const imageRenderer = new ImageRenderer({pixelArtSampler: false, uvPadding: 0}); + const imageRenderer = new ImageRenderer({ pixelArtSampler: false, uvPadding: 0 }); imageRenderer.initialize(webgl.__gl, webgl); spyOn(webgl.textureLoader, 'load').and.callThrough(); @@ -107,7 +110,9 @@ describe('A ImageSource', () => { x: ex.ImageWrapping.Clamp, y: ex.ImageWrapping.Clamp } - }, false); + }, + false + ); }); it('can load images with an image filtering Pixel', async () => { @@ -115,7 +120,7 @@ describe('A ImageSource', () => { const webgl = new ex.ExcaliburGraphicsContextWebGL({ canvasElement: canvas }); - const imageRenderer = new ImageRenderer({pixelArtSampler: false, uvPadding: 0}); + const imageRenderer = new ImageRenderer({ pixelArtSampler: false, uvPadding: 0 }); imageRenderer.initialize(webgl.__gl, webgl); spyOn(webgl.textureLoader, 'load').and.callThrough(); @@ -136,7 +141,9 @@ describe('A ImageSource', () => { x: ex.ImageWrapping.Clamp, y: ex.ImageWrapping.Clamp } - }, false); + }, + false + ); }); it('can load images with an image wrap repeat', async () => { @@ -144,11 +151,11 @@ describe('A ImageSource', () => { const webgl = new ex.ExcaliburGraphicsContextWebGL({ canvasElement: canvas }); - const imageRenderer = new ImageRenderer({pixelArtSampler: false, uvPadding: 0}); + const imageRenderer = new ImageRenderer({ pixelArtSampler: false, uvPadding: 0 }); imageRenderer.initialize(webgl.__gl, webgl); spyOn(webgl.textureLoader, 'load').and.callThrough(); - const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png',{ + const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png', { filtering: ex.ImageFiltering.Pixel, wrapping: ex.ImageWrapping.Repeat }); @@ -168,7 +175,9 @@ describe('A ImageSource', () => { x: ex.ImageWrapping.Repeat, y: ex.ImageWrapping.Repeat } - }, false); + }, + false + ); }); it('can load images with an image wrap repeat', async () => { @@ -176,11 +185,11 @@ describe('A ImageSource', () => { const webgl = new ex.ExcaliburGraphicsContextWebGL({ canvasElement: canvas }); - const imageRenderer = new ImageRenderer({pixelArtSampler: false, uvPadding: 0}); + const imageRenderer = new ImageRenderer({ pixelArtSampler: false, uvPadding: 0 }); imageRenderer.initialize(webgl.__gl, webgl); spyOn(webgl.textureLoader, 'load').and.callThrough(); - const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png',{ + const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png', { filtering: ex.ImageFiltering.Pixel, wrapping: ex.ImageWrapping.Mirror }); @@ -200,7 +209,9 @@ describe('A ImageSource', () => { x: ex.ImageWrapping.Mirror, y: ex.ImageWrapping.Mirror } - }, false); + }, + false + ); }); it('can load images with an image wrap mixed', async () => { @@ -208,13 +219,13 @@ describe('A ImageSource', () => { const webgl = new ex.ExcaliburGraphicsContextWebGL({ canvasElement: canvas }); - const imageRenderer = new ImageRenderer({pixelArtSampler: false, uvPadding: 0}); + const imageRenderer = new ImageRenderer({ pixelArtSampler: false, uvPadding: 0 }); imageRenderer.initialize(webgl.__gl, webgl); spyOn(webgl.textureLoader, 'load').and.callThrough(); const texParameteri = spyOn(webgl.__gl, 'texParameteri').and.callThrough(); const gl = webgl.__gl; - const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png',{ + const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png', { filtering: ex.ImageFiltering.Pixel, wrapping: { x: ex.ImageWrapping.Mirror, @@ -239,7 +250,9 @@ describe('A ImageSource', () => { x: ex.ImageWrapping.Mirror, y: ex.ImageWrapping.Clamp } - }, false); + }, + false + ); }); it('can convert to a Sprite', async () => { @@ -286,11 +299,9 @@ describe('A ImageSource', () => { ); }); - it('will return error if image doesn\'t exist', async () => { + it("will return error if image doesn't exist", async () => { const spriteFontImage = new ex.ImageSource('42.png'); - await expectAsync(spriteFontImage.load()).toBeRejectedWith( - 'Error loading ImageSource from path \'42.png\' with error [Not Found]' - ); + await expectAsync(spriteFontImage.load()).toBeRejectedWith("Error loading ImageSource from path '42.png' with error [Not Found]"); }); }); diff --git a/src/spec/InputMapperSpec.ts b/src/spec/InputMapperSpec.ts index 5db3eb93..cd98f743 100644 --- a/src/spec/InputMapperSpec.ts +++ b/src/spec/InputMapperSpec.ts @@ -16,10 +16,10 @@ describe('An InputMapper', () => { gamepads: {} as any }); - sut.on(({keyboard}) => { + sut.on(({ keyboard }) => { return keyboard.isHeld(ex.Keys.Enter); }, command); - sut.on(({keyboard}) => { + sut.on(({ keyboard }) => { return keyboard.isHeld(ex.Keys.ArrowRight); }, command); @@ -38,10 +38,10 @@ describe('An InputMapper', () => { gamepads: {} as any }); - sut.on(({keyboard}) => { + sut.on(({ keyboard }) => { return keyboard.isHeld(ex.Keys.Enter); }, command); - sut.on(({keyboard}) => { + sut.on(({ keyboard }) => { return keyboard.isHeld(ex.Keys.ArrowRight); }, command); @@ -51,7 +51,6 @@ describe('An InputMapper', () => { }); it('can fire wasPressed events when used in a engine', async () => { - const engine = TestUtils.engine({ width: 100, height: 100 }); await TestUtils.runToReady(engine); const clock = engine.clock as ex.TestClock; @@ -61,8 +60,8 @@ describe('An InputMapper', () => { const sut = engine.inputMapper; const keyPressedSpy = jasmine.createSpy('keyPressed'); const keyReleasedSpy = jasmine.createSpy('keyReleased'); - sut.on(({keyboard}) => keyboard.wasPressed(ex.Keys.Space), keyPressedSpy); - sut.on(({keyboard}) => keyboard.wasReleased(ex.Keys.Space), keyReleasedSpy); + sut.on(({ keyboard }) => keyboard.wasPressed(ex.Keys.Space), keyPressedSpy); + sut.on(({ keyboard }) => keyboard.wasReleased(ex.Keys.Space), keyReleasedSpy); clock.step(); expect(keyPressedSpy).toHaveBeenCalled(); @@ -72,4 +71,4 @@ describe('An InputMapper', () => { expect(keyReleasedSpy).toHaveBeenCalled(); engine.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/IsometricMapSpec.ts b/src/spec/IsometricMapSpec.ts index 44711ef3..512cc901 100644 --- a/src/spec/IsometricMapSpec.ts +++ b/src/spec/IsometricMapSpec.ts @@ -40,7 +40,7 @@ describe('A IsometricMap', () => { rows: 15 }); - sut.tiles.forEach(tile => tile.addGraphic(sprite)); + sut.tiles.forEach((tile) => tile.addGraphic(sprite)); engine.add(sut); clock.step(100); @@ -67,7 +67,7 @@ describe('A IsometricMap', () => { rows: 15 }); - sut.tiles.forEach(tile => tile.addGraphic(sprite)); + sut.tiles.forEach((tile) => tile.addGraphic(sprite)); engine.add(sut); clock.step(100); @@ -93,7 +93,7 @@ describe('A IsometricMap', () => { rows: 15 }); - sut.tiles.forEach(tile => tile.addGraphic(sprite)); + sut.tiles.forEach((tile) => tile.addGraphic(sprite)); engine.add(sut); clock.step(100); @@ -125,7 +125,7 @@ describe('A IsometricMap', () => { rows: 15 }); - sut.tiles.forEach(tile => tile.addGraphic(sprite)); + sut.tiles.forEach((tile) => tile.addGraphic(sprite)); engine.add(sut); clock.step(100); @@ -183,7 +183,7 @@ describe('A IsometricMap', () => { expect(sut.tileToWorld(ex.vec(14, 0))).toBeVector(ex.vec(474, 122)); expect(sut.tileToWorld(ex.vec(14, 14))).toBeVector(ex.vec(250, 234)); - expect(sut.tiles[sut.tiles.length-1].pos).toBeVector(ex.vec(250, 234)); + expect(sut.tiles[sut.tiles.length - 1].pos).toBeVector(ex.vec(250, 234)); expect(sut.tileToWorld(ex.vec(0, 14))).toBeVector(ex.vec(26, 122)); engine.dispose(); @@ -302,7 +302,7 @@ describe('A IsometricMap', () => { }); it('can respond to pointer events', async () => { - const engine = TestUtils.engine({width: 100, height: 100}); + const engine = TestUtils.engine({ width: 100, height: 100 }); await TestUtils.runToReady(engine); const sut = new ex.IsometricMap({ pos: ex.vec(100, 100), @@ -335,5 +335,4 @@ describe('A IsometricMap', () => { engine.dispose(); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/KeyInputSpec.ts b/src/spec/KeyInputSpec.ts index 1620a42a..ac0dcae6 100644 --- a/src/spec/KeyInputSpec.ts +++ b/src/spec/KeyInputSpec.ts @@ -9,7 +9,7 @@ describe('A keyboard', () => { beforeEach(() => { mockWindow = mocker.window(); keyboard = new ex.Keyboard(); - keyboard.init({global: mockWindow}); + keyboard.init({ global: mockWindow }); }); it('should exist', () => { diff --git a/src/spec/LabelSpec.ts b/src/spec/LabelSpec.ts index 93076060..fb9596be 100644 --- a/src/spec/LabelSpec.ts +++ b/src/spec/LabelSpec.ts @@ -26,7 +26,7 @@ describe('A label', () => { }); it('can be constructed', () => { - const sut = new ex.Label({text: 'some text'}); + const sut = new ex.Label({ text: 'some text' }); expect(sut).not.toBeNull(); }); diff --git a/src/spec/LineSpec.ts b/src/spec/LineSpec.ts index d06fa26b..46d186ba 100644 --- a/src/spec/LineSpec.ts +++ b/src/spec/LineSpec.ts @@ -122,4 +122,4 @@ describe('A Line', () => { game.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/LoaderSpec.ts b/src/spec/LoaderSpec.ts index 79ebf75f..b65fa206 100644 --- a/src/spec/LoaderSpec.ts +++ b/src/spec/LoaderSpec.ts @@ -102,11 +102,12 @@ describe('A loader', () => { loader.showPlayButton(); loader.onDraw(loader.canvas.ctx); - ensureImagesLoaded(loader.canvas.ctx.canvas, 'src/spec/images/LoaderSpec/playbuttonshown-noprogressbar.png') - .then(([canvas, image]) => { + ensureImagesLoaded(loader.canvas.ctx.canvas, 'src/spec/images/LoaderSpec/playbuttonshown-noprogressbar.png').then( + ([canvas, image]) => { expect(canvas).toEqualImage(image); done(); - }); + } + ); }; }); @@ -226,7 +227,7 @@ describe('A loader', () => { engine = null; engine = new ex.Engine({ width: 1000, height: 1000 }); (ex.WebAudio as any)._UNLOCKED = true; - const clock = engine.clock = engine.clock.toTestClock(); + const clock = (engine.clock = engine.clock.toTestClock()); const pointerHandler = jasmine.createSpy('pointerHandler'); engine.input.pointers.primary.on('up', pointerHandler); const loader = new ex.Loader([new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png')]); @@ -261,17 +262,13 @@ describe('A loader', () => { engine.browser.window.nativeComponent.dispatchEvent(new Event('resize')); - const oldPos = [ - loader.playButtonRootElement.style.left, - loader.playButtonRootElement.style.top]; + const oldPos = [loader.playButtonRootElement.style.left, loader.playButtonRootElement.style.top]; engine.screen.viewport = { width: 100, height: 100 }; engine.browser.window.nativeComponent.dispatchEvent(new Event('resize')); - const newPos = [ - loader.playButtonRootElement.style.left, - loader.playButtonRootElement.style.top]; + const newPos = [loader.playButtonRootElement.style.left, loader.playButtonRootElement.style.top]; expect(oldPos).not.toEqual(newPos); }); @@ -327,7 +324,7 @@ describe('A loader', () => { for (let i = 0; i < 800; i++) { srcs.push(generateRandomImage()); } - const images = srcs.map(src => new ex.ImageSource(src)); + const images = srcs.map((src) => new ex.ImageSource(src)); images.forEach((image) => { image.ready.then(() => { testClock.step(1); @@ -335,11 +332,12 @@ describe('A loader', () => { }); loader.addResources(images); - const ready = TestUtils.runToReady(game, loader).then(() => { - expect(logger.error).not.toHaveBeenCalled(); - game.dispose(); - done(); - }) + const ready = TestUtils.runToReady(game, loader) + .then(() => { + expect(logger.error).not.toHaveBeenCalled(); + game.dispose(); + done(); + }) .catch(() => { fail(); }); diff --git a/src/spec/MaterialRendererSpec.ts b/src/spec/MaterialRendererSpec.ts index 0149a246..8716e23a 100644 --- a/src/spec/MaterialRendererSpec.ts +++ b/src/spec/MaterialRendererSpec.ts @@ -96,13 +96,11 @@ describe('A Material', () => { graphicsContext.restore(); expect(graphicsContext.material).toBe(null); - await expectAsync(canvas) - .toEqualImage('src/spec/images/MaterialRendererSpec/material.png'); + await expectAsync(canvas).toEqualImage('src/spec/images/MaterialRendererSpec/material.png'); graphicsContext.dispose(); }); it('can draw the screen texture', async () => { - const canvas = document.createElement('canvas'); canvas.width = 100; canvas.height = 100; @@ -141,13 +139,11 @@ describe('A Material', () => { context.restore(); expect(context.material).toBe(null); - await expectAsync(canvas) - .toEqualImage('src/spec/images/MaterialRendererSpec/multiply-comp.png'); + await expectAsync(canvas).toEqualImage('src/spec/images/MaterialRendererSpec/multiply-comp.png'); context.dispose(); }); it('can update uniforms with the .update()', async () => { - const canvas = document.createElement('canvas'); canvas.width = 100; canvas.height = 100; @@ -182,7 +178,7 @@ describe('A Material', () => { context.clear(); context.save(); context.material = material; - material.update(shader => { + material.update((shader) => { shader.setUniformFloatColor('customcolor', ex.Color.Red); }); context.drawImage(tex.image, 0, 0); @@ -190,8 +186,7 @@ describe('A Material', () => { context.restore(); expect(context.material).toBe(null); - await expectAsync(canvas) - .toEqualImage('src/spec/images/MaterialRendererSpec/update-uniform.png'); + await expectAsync(canvas).toEqualImage('src/spec/images/MaterialRendererSpec/update-uniform.png'); }); it('can be created with a custom fragment shader with the graphics component', async () => { @@ -223,8 +218,6 @@ describe('A Material', () => { }` }); - - const tex = new ex.ImageSource('src/spec/images/MaterialRendererSpec/sword.png'); const loader = new ex.Loader([tex]); @@ -246,8 +239,7 @@ describe('A Material', () => { graphicsContext.flush(); expect(graphicsContext.material).toBe(null); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/MaterialRendererSpec/material-component.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/MaterialRendererSpec/material-component.png'); engine.dispose(); }); @@ -285,8 +277,6 @@ describe('A Material', () => { }` }); - - const tex = new ex.ImageSource('src/spec/images/MaterialRendererSpec/sword.png'); const loader = new ex.Loader([tex]); @@ -318,13 +308,11 @@ describe('A Material', () => { graphicsContext.flush(); expect(graphicsContext.material).toBe(null); - await expectAsync(engine.canvas) - .toEqualImage('src/spec/images/MaterialRendererSpec/multi-mat.png'); + await expectAsync(engine.canvas).toEqualImage('src/spec/images/MaterialRendererSpec/multi-mat.png'); engine.dispose(); }); - it('will allow addition images', async () => { const canvas = document.createElement('canvas'); canvas.width = 100; @@ -374,8 +362,7 @@ describe('A Material', () => { graphicsContext.restore(); expect(graphicsContext.material).toBe(null); - await expectAsync(canvas) - .toEqualImage('src/spec/images/MaterialRendererSpec/additional.png'); + await expectAsync(canvas).toEqualImage('src/spec/images/MaterialRendererSpec/additional.png'); }); it('will log a warning if you exceed you texture slots', () => { @@ -452,6 +439,7 @@ describe('A Material', () => { expect(material).toBeDefined(); expect(logger.warn).toHaveBeenCalledWith( - 'Max number texture slots 30 have been reached for material "test", no more textures will be uploaded due to hardware constraints.'); + 'Max number texture slots 30 have been reached for material "test", no more textures will be uploaded due to hardware constraints.' + ); }); -}); \ No newline at end of file +}); diff --git a/src/spec/MathSpec.ts b/src/spec/MathSpec.ts index a5d6054a..918709d9 100644 --- a/src/spec/MathSpec.ts +++ b/src/spec/MathSpec.ts @@ -41,8 +41,8 @@ describe('Excalibur Math', () => { }); it('can get the fractional portion of a number', () => { - expect(ex.frac(42.123)).toBeCloseTo(.123); - expect(ex.frac(-42.123)).toBeCloseTo(-.123); + expect(ex.frac(42.123)).toBeCloseTo(0.123); + expect(ex.frac(-42.123)).toBeCloseTo(-0.123); }); it('can return the sign of a number', () => { diff --git a/src/spec/MatrixSpec.ts b/src/spec/MatrixSpec.ts index e7d85682..36493595 100644 --- a/src/spec/MatrixSpec.ts +++ b/src/spec/MatrixSpec.ts @@ -131,9 +131,7 @@ describe('A Matrix', () => { }); it('can find the affine inverse', () => { - const mat = ex.Matrix.identity() - .translate(100, -200) - .scale(2, 4); + const mat = ex.Matrix.identity().translate(100, -200).scale(2, 4); const inv = mat.getAffineInverse(); expect(mat.multiply(inv).isIdentity()).toBeTrue(); @@ -142,21 +140,18 @@ describe('A Matrix', () => { it('can find the affine inverse and store it into a target', () => { const target = ex.Matrix.identity(); - const mat = ex.Matrix.identity() - .translate(100, -200) - .scale(2, 4); + const mat = ex.Matrix.identity().translate(100, -200).scale(2, 4); spyOn(ex.Matrix, 'identity'); const inv = mat.getAffineInverse(target); expect(mat.multiply(inv).isIdentity()).toBeTrue(); expect(inv.multiply(mat).isIdentity()).toBeTrue(); expect(target).toBe(inv); - expect(ex.Matrix.identity).withContext('using a target doesnt create a new mat') - .not.toHaveBeenCalledWith(); + expect(ex.Matrix.identity).withContext('using a target doesnt create a new mat').not.toHaveBeenCalledWith(); }); it('can be created from a float32array', () => { - const mat = ex.Matrix.identity().translate(1,2).rotate(Math.PI).scale(3, 4); + const mat = ex.Matrix.identity().translate(1, 2).rotate(Math.PI).scale(3, 4); const newData = new Float32Array(mat.data); const mat2 = ex.Matrix.fromFloat32Array(newData); expect(mat.toString()).toEqual(mat2.toString()); @@ -175,18 +170,11 @@ describe('A Matrix', () => { source.clone(destination); - expect(destination.data).toEqual(new Float32Array([ - 5, 0, 0, 0, - 0, 5, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ])); + expect(destination.data).toEqual(new Float32Array([5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])); }); it('can reset to identity', () => { - const mat = ex.Matrix.identity() - .translate(100, -200) - .scale(2, 4); + const mat = ex.Matrix.identity().translate(100, -200).scale(2, 4); mat.reset(); expect(mat.isIdentity()).toBe(true); @@ -201,4 +189,4 @@ describe('A Matrix', () => { [0 0 0 1] `); }); -}); \ No newline at end of file +}); diff --git a/src/spec/MotionComponentSpec.ts b/src/spec/MotionComponentSpec.ts index 57e9aa6d..8e9c322a 100644 --- a/src/spec/MotionComponentSpec.ts +++ b/src/spec/MotionComponentSpec.ts @@ -37,4 +37,4 @@ describe('A Motion Component', () => { // Should have a new owner expect(sut.owner).toBe(clone); }); -}); \ No newline at end of file +}); diff --git a/src/spec/OffscreenSystemSpec.ts b/src/spec/OffscreenSystemSpec.ts index 51b71b86..57bbd3df 100644 --- a/src/spec/OffscreenSystemSpec.ts +++ b/src/spec/OffscreenSystemSpec.ts @@ -72,4 +72,4 @@ describe('The OffscreenSystem', () => { expect(onscreenSpy).toHaveBeenCalled(); expect(offscreen.hasTag('ex.offscreen')).toBeFalse(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/PairSpec.ts b/src/spec/PairSpec.ts index 55e03e66..c05eda0a 100644 --- a/src/spec/PairSpec.ts +++ b/src/spec/PairSpec.ts @@ -53,10 +53,7 @@ describe('A Collision Pair', () => { const actor1 = new ex.Actor(); const collider1 = ex.Shape.Circle(50); const collider2 = ex.Shape.Box(100, 100); - actor1.collider.useCompositeCollider([ - collider1, - collider2 - ]); + actor1.collider.useCompositeCollider([collider1, collider2]); const sut = ex.Pair.canCollide(collider1, collider2); @@ -95,4 +92,4 @@ describe('A Collision Pair', () => { expect(sut).toBe(false); }); -}); \ No newline at end of file +}); diff --git a/src/spec/ParallaxSpec.ts b/src/spec/ParallaxSpec.ts index f1f45c24..f4417118 100644 --- a/src/spec/ParallaxSpec.ts +++ b/src/spec/ParallaxSpec.ts @@ -2,7 +2,6 @@ import * as ex from '@excalibur'; import { ExcaliburAsyncMatchers, ExcaliburMatchers } from 'excalibur-jasmine'; import { TestUtils } from './util/TestUtils'; - describe('A Parallax Component', () => { beforeAll(() => { jasmine.addMatchers(ExcaliburMatchers); @@ -13,7 +12,7 @@ describe('A Parallax Component', () => { }); it('can be added to an actor', () => { - const actor = new ex.Actor({x: 100, y: 100}); + const actor = new ex.Actor({ x: 100, y: 100 }); actor.addComponent(new ex.ParallaxComponent(ex.vec(0.5, 0.5))); const comp = actor.get(ex.ParallaxComponent); @@ -22,14 +21,14 @@ describe('A Parallax Component', () => { }); it('will apply a parallax effect to the graphics', async () => { - const game = TestUtils.engine({width: 500, height: 500}, ['use-canvas-context']); + const game = TestUtils.engine({ width: 500, height: 500 }, ['use-canvas-context']); await TestUtils.runToReady(game); game.currentScene.camera.pos = ex.vec(0, 0); game.currentScene.camera.drawPos = ex.vec(0, 0); const clock = game.clock as ex.TestClock; - const actor = new ex.Actor({x: 0, y: 0, width: 120, height: 120, color: ex.Color.Green}); + const actor = new ex.Actor({ x: 0, y: 0, width: 120, height: 120, color: ex.Color.Green }); actor.addComponent(new ex.ParallaxComponent(ex.vec(0.5, 0.5))); game.add(actor); @@ -57,7 +56,7 @@ describe('A Parallax Component', () => { }); it('works with TileMaps correctly', async () => { - const game = TestUtils.engine({width: 500, height: 500}); + const game = TestUtils.engine({ width: 500, height: 500 }); await TestUtils.runToReady(game); const clock = game.clock as ex.TestClock; @@ -73,7 +72,7 @@ describe('A Parallax Component', () => { rows: 4, columns: 4 }); - tilemap.tiles.forEach(t => { + tilemap.tiles.forEach((t) => { t.addGraphic(graphic); }); tilemap.addComponent(new ex.ParallaxComponent(ex.vec(0.5, 0.5))); @@ -93,4 +92,4 @@ describe('A Parallax Component', () => { await expectAsync(game.canvas).toEqualImage('src/spec/images/ParallaxSpec/tilemap2.png'); game.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/ParticleSpec.ts b/src/spec/ParticleSpec.ts index 691cd883..4818c5e8 100644 --- a/src/spec/ParticleSpec.ts +++ b/src/spec/ParticleSpec.ts @@ -21,7 +21,6 @@ describe('A particle', () => { await TestUtils.runToReady(engine); const clock = engine.clock as ex.TestClock; clock.step(1); - }); afterEach(() => { engine.stop(); @@ -176,7 +175,6 @@ describe('A particle', () => { engine.currentScene.draw(engine.graphicsContext, 100); engine.graphicsContext.flush(); await expectAsync(engine.canvas).toEqualImage('src/spec/images/ParticleSpec/parented.png'); - }); it('can set the particle transform to local making particles children of the emitter', () => { diff --git a/src/spec/PhysicsWorldSpec.ts b/src/spec/PhysicsWorldSpec.ts index 93ff6313..c8bed71a 100644 --- a/src/spec/PhysicsWorldSpec.ts +++ b/src/spec/PhysicsWorldSpec.ts @@ -11,9 +11,9 @@ describe('A physics world', () => { it('can rayCast with default options, only 1 hit is returned, searches all groups', () => { const sut = TestUtils.engine(); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor2); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -29,9 +29,9 @@ describe('A physics world', () => { it('can rayCast with searchAllColliders on, all hits is returned, searches all groups', () => { const sut = TestUtils.engine(); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor2); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -56,9 +56,9 @@ describe('A physics world', () => { const sut = TestUtils.engine(); const collisionGroup1 = ex.CollisionGroupManager.create('somegroup1'); const collisionGroup2 = ex.CollisionGroupManager.create('somegroup2'); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50, collisionGroup: collisionGroup1}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50, collisionGroup: collisionGroup1 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50, collisionGroup: collisionGroup2}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50, collisionGroup: collisionGroup2 }); sut.currentScene.add(actor2); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -79,9 +79,9 @@ describe('A physics world', () => { const sut = TestUtils.engine(); const collisionGroup1 = ex.CollisionGroupManager.create('somegroup1'); const collisionGroup2 = ex.CollisionGroupManager.create('somegroup2'); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50, collisionGroup: collisionGroup1}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50, collisionGroup: collisionGroup1 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50, collisionGroup: collisionGroup2}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50, collisionGroup: collisionGroup2 }); sut.currentScene.add(actor2); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -104,9 +104,9 @@ describe('A physics world', () => { it('can rayCast with searchAllColliders on and max distance set, returns 1 hit', () => { const sut = TestUtils.engine(); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor2); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -125,11 +125,11 @@ describe('A physics world', () => { it('can rayCast with ignoreCollisionGroupAll, returns 1 hit', () => { const sut = TestUtils.engine(); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor2); - const actor3 = new ex.Actor({x: 300, y: 0, width: 50, height: 50, collisionGroup: new ex.CollisionGroup('test', 0b1, ~0b1)}); + const actor3 = new ex.Actor({ x: 300, y: 0, width: 50, height: 50, collisionGroup: new ex.CollisionGroup('test', 0b1, ~0b1) }); sut.currentScene.add(actor3); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -149,11 +149,11 @@ describe('A physics world', () => { it('can rayCast with filter, returns 1 hit', () => { const sut = TestUtils.engine(); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor2); - const actor3 = new ex.Actor({x: 300, y: 0, width: 50, height: 50, collisionGroup: new ex.CollisionGroup('test', 0b1, ~0b1)}); + const actor3 = new ex.Actor({ x: 300, y: 0, width: 50, height: 50, collisionGroup: new ex.CollisionGroup('test', 0b1, ~0b1) }); sut.currentScene.add(actor3); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -174,11 +174,11 @@ describe('A physics world', () => { it('can rayCast with filter and search all colliders false, returns 1 hit', () => { const sut = TestUtils.engine(); - const actor1 = new ex.Actor({x: 100, y: 0, width: 50, height: 50}); + const actor1 = new ex.Actor({ x: 100, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor1); - const actor2 = new ex.Actor({x: 200, y: 0, width: 50, height: 50}); + const actor2 = new ex.Actor({ x: 200, y: 0, width: 50, height: 50 }); sut.currentScene.add(actor2); - const actor3 = new ex.Actor({x: 300, y: 0, width: 50, height: 50, collisionGroup: new ex.CollisionGroup('test', 0b1, ~0b1)}); + const actor3 = new ex.Actor({ x: 300, y: 0, width: 50, height: 50, collisionGroup: new ex.CollisionGroup('test', 0b1, ~0b1) }); sut.currentScene.add(actor3); const ray = new ex.Ray(ex.vec(0, 0), ex.Vector.Right); @@ -196,4 +196,4 @@ describe('A physics world', () => { expect(hits[0].point).toEqual(ex.vec(275, 0)); sut.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/PointerInputSpec.ts b/src/spec/PointerInputSpec.ts index b6d39431..187e655f 100644 --- a/src/spec/PointerInputSpec.ts +++ b/src/spec/PointerInputSpec.ts @@ -203,7 +203,6 @@ describe('A pointer', () => { engine.currentScene.update(engine, 0); expect(pointerDownSpy).toHaveBeenCalledTimes(0); - }); it('can have pointer event canceled', () => { diff --git a/src/spec/PostProcessorSpec.ts b/src/spec/PostProcessorSpec.ts index 127c16da..f7a45473 100644 --- a/src/spec/PostProcessorSpec.ts +++ b/src/spec/PostProcessorSpec.ts @@ -73,7 +73,5 @@ describe('A PostProcessor', () => { expect(setUniformFloatCalls.calls.argsFor(0)).toEqual(['u_time_ms', 10]); expect(setUniformFloatCalls.calls.argsFor(1)).toEqual(['u_elapsed_ms', 10]); expect(setUniformFloatVectorCalls.calls.argsFor(0)).toEqual(['u_resolution', ex.vec(100, 100)]); - }); - -}); \ No newline at end of file +}); diff --git a/src/spec/QuadIndexBufferSpec.ts b/src/spec/QuadIndexBufferSpec.ts index 32973cdf..804c34d6 100644 --- a/src/spec/QuadIndexBufferSpec.ts +++ b/src/spec/QuadIndexBufferSpec.ts @@ -54,5 +54,4 @@ describe('A QuadIndexBuffer', () => { const sut = new ex.QuadIndexBuffer(gl, 16384, true); expect(logger.warn).toHaveBeenCalledWith('Total quads exceeds hardware index buffer limit (uint16), max(16383) requested quads(16384)'); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/QuadTreeSpec.ts b/src/spec/QuadTreeSpec.ts index 94bacbb9..63e01895 100644 --- a/src/spec/QuadTreeSpec.ts +++ b/src/spec/QuadTreeSpec.ts @@ -2,20 +2,19 @@ import * as ex from '@excalibur'; import { ExcaliburMatchers } from 'excalibur-jasmine'; describe('A QuadTree', () => { - it('exists', () => { expect(ex.QuadTree).toBeDefined(); }); it('can add things to track', () => { - const sut = new ex.QuadTree<{ id: number, bounds: ex.BoundingBox }>( + const sut = new ex.QuadTree<{ id: number; bounds: ex.BoundingBox }>( new ex.BoundingBox({ left: 0, top: 0, bottom: 100, right: 100 - })); - + }) + ); const bb1 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(0, 0)); const bb2 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(90, 90)); @@ -31,16 +30,17 @@ describe('A QuadTree', () => { }); it('can remove things', () => { - const sut = new ex.QuadTree<{ id: number, bounds: ex.BoundingBox }>( + const sut = new ex.QuadTree<{ id: number; bounds: ex.BoundingBox }>( new ex.BoundingBox({ left: 0, top: 0, bottom: 100, right: 100 - }), { + }), + { capacity: 1 - }); - + } + ); const bb1 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(0, 0)); const bb2 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(90, 90)); @@ -70,14 +70,14 @@ describe('A QuadTree', () => { }); it('can be cleared', () => { - const sut = new ex.QuadTree<{ id: number, bounds: ex.BoundingBox }>( + const sut = new ex.QuadTree<{ id: number; bounds: ex.BoundingBox }>( new ex.BoundingBox({ left: 0, top: 0, bottom: 100, right: 100 - })); - + }) + ); const bb1 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(0, 0)); const bb2 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(90, 90)); @@ -99,16 +99,17 @@ describe('A QuadTree', () => { }); it('can be queried', () => { - const sut = new ex.QuadTree<{ id: number, bounds: ex.BoundingBox }>( + const sut = new ex.QuadTree<{ id: number; bounds: ex.BoundingBox }>( new ex.BoundingBox({ left: 0, top: 0, bottom: 100, right: 100 - }), { + }), + { capacity: 1 - }); - + } + ); const bb1 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(0, 0)); const bb2 = ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.vec(90, 90)); @@ -135,20 +136,22 @@ describe('A QuadTree', () => { }); it('will respect max depth', () => { - const sut = new ex.QuadTree<{ id: number, bounds: ex.BoundingBox }>( + const sut = new ex.QuadTree<{ id: number; bounds: ex.BoundingBox }>( new ex.BoundingBox({ left: 0, top: 0, bottom: 100, right: 100 - }), { + }), + { capacity: 1, maxDepth: 10 - }); + } + ); let id = 0; for (let i = 0; i < 15; i++) { - sut.insert({id: id++, bounds: ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.Vector.Zero)}); + sut.insert({ id: id++, bounds: ex.BoundingBox.fromDimension(10, 10, ex.Vector.Zero, ex.Vector.Zero) }); } const items = sut.getAllItems(); @@ -158,4 +161,4 @@ describe('A QuadTree', () => { expect(depth).toBe(10); }); -}); \ No newline at end of file +}); diff --git a/src/spec/QueryManagerSpec.ts b/src/spec/QueryManagerSpec.ts index 7f328dcf..60277305 100644 --- a/src/spec/QueryManagerSpec.ts +++ b/src/spec/QueryManagerSpec.ts @@ -17,11 +17,11 @@ describe('A QueryManager', () => { it('can create queries for entities', () => { const world = new ex.World(null); const entity1 = new ex.Entity(); - entity1.addComponent(new FakeComponentA); - entity1.addComponent(new FakeComponentB); + entity1.addComponent(new FakeComponentA()); + entity1.addComponent(new FakeComponentB()); const entity2 = new ex.Entity(); - entity2.addComponent(new FakeComponentA); + entity2.addComponent(new FakeComponentA()); world.entityManager.addEntity(entity1); world.entityManager.addEntity(entity2); @@ -35,11 +35,8 @@ describe('A QueryManager', () => { expect(queryAB.getEntities()).toEqual([entity1], 'Only entity1 has both A+B'); // Queries update if component change - entity2.addComponent(new FakeComponentB); - expect(queryAB.getEntities()).toEqual( - [entity1, entity2], - 'Now both entities have A+B' - ); + entity2.addComponent(new FakeComponentB()); + expect(queryAB.getEntities()).toEqual([entity1, entity2], 'Now both entities have A+B'); // Queries update if components change entity2.removeComponent(FakeComponentB, true); @@ -55,12 +52,12 @@ describe('A QueryManager', () => { it('can add entities to queries', () => { const world = new ex.World(null); const entity1 = new ex.Entity(); - entity1.addComponent(new FakeComponentA); - entity1.addComponent(new FakeComponentB); + entity1.addComponent(new FakeComponentA()); + entity1.addComponent(new FakeComponentB()); const entity2 = new ex.Entity(); - entity2.addComponent(new FakeComponentA); - entity2.addComponent(new FakeComponentB); + entity2.addComponent(new FakeComponentA()); + entity2.addComponent(new FakeComponentB()); const queryAB = world.query([FakeComponentA, FakeComponentB]); expect(queryAB.getEntities()).toEqual([]); @@ -95,12 +92,12 @@ describe('A QueryManager', () => { it('can remove entities from queries', () => { const world = new ex.World(null); const entity1 = new ex.Entity(); - entity1.addComponent(new FakeComponentA); - entity1.addComponent(new FakeComponentB); + entity1.addComponent(new FakeComponentA()); + entity1.addComponent(new FakeComponentB()); const entity2 = new ex.Entity(); - entity2.addComponent(new FakeComponentA); - entity2.addComponent(new FakeComponentB); + entity2.addComponent(new FakeComponentA()); + entity2.addComponent(new FakeComponentB()); const queryAB = world.query([FakeComponentA, FakeComponentB]); world.queryManager.addEntity(entity1); @@ -139,12 +136,12 @@ describe('A QueryManager', () => { it('can update queries when a component is removed', () => { const world = new ex.World(null); const entity1 = new ex.Entity(); - entity1.addComponent(new FakeComponentA); - entity1.addComponent(new FakeComponentB); + entity1.addComponent(new FakeComponentA()); + entity1.addComponent(new FakeComponentB()); const entity2 = new ex.Entity(); - entity2.addComponent(new FakeComponentA); - entity2.addComponent(new FakeComponentB); + entity2.addComponent(new FakeComponentA()); + entity2.addComponent(new FakeComponentB()); const queryAB = world.query([FakeComponentA, FakeComponentB]); world.queryManager.addEntity(entity1); @@ -181,16 +178,16 @@ describe('A QueryManager', () => { expect(queryAB.getEntities()).toEqual([entity2]); }); - it('removing components unrelated to the query doesn\'t remove the entity', () => { + it("removing components unrelated to the query doesn't remove the entity", () => { const world = new ex.World(null); const entity1 = new ex.Entity(); - entity1.addComponent(new FakeComponentA); - entity1.addComponent(new FakeComponentB); - entity1.addComponent(new FakeComponentC); + entity1.addComponent(new FakeComponentA()); + entity1.addComponent(new FakeComponentB()); + entity1.addComponent(new FakeComponentC()); const entity2 = new ex.Entity(); - entity2.addComponent(new FakeComponentA); - entity2.addComponent(new FakeComponentB); + entity2.addComponent(new FakeComponentA()); + entity2.addComponent(new FakeComponentB()); const queryAB = world.query([FakeComponentA, FakeComponentB]); world.queryManager.addEntity(entity1); @@ -210,9 +207,9 @@ describe('A QueryManager', () => { const entity = new ex.Entity(); world.add(entity); - const componentA = new FakeComponentA; + const componentA = new FakeComponentA(); const query = world.query([FakeComponentA]); - query.entityAdded$.subscribe(e => { + query.entityAdded$.subscribe((e) => { expect(e).toBe(entity); expect(e.get(FakeComponentA)).toBe(componentA); done(); @@ -225,11 +222,11 @@ describe('A QueryManager', () => { const world = new ex.World(null); const entity = new ex.Entity(); world.add(entity); - const componentA = new FakeComponentA; + const componentA = new FakeComponentA(); entity.addComponent(componentA); const query = world.query([FakeComponentA]); - query.entityRemoved$.subscribe(e => { + query.entityRemoved$.subscribe((e) => { expect(e).toBe(entity); expect(e.get(FakeComponentA)).toBe(componentA); done(); diff --git a/src/spec/QuerySpec.ts b/src/spec/QuerySpec.ts index cf34f77a..fe2738ef 100644 --- a/src/spec/QuerySpec.ts +++ b/src/spec/QuerySpec.ts @@ -19,8 +19,8 @@ describe('A query', () => { it('can match with entities', () => { const queryAB = new ex.Query([FakeComponentA, FakeComponentB]); - const compA = new FakeComponentA; - const compB = new FakeComponentB; + const compA = new FakeComponentA(); + const compB = new FakeComponentB(); const entity1 = new ex.Entity(); entity1.addComponent(compA); entity1.addComponent(compB); @@ -34,8 +34,8 @@ describe('A query', () => { it('can only add entities that match', () => { const queryAB = new ex.Query([FakeComponentA, FakeComponentB]); - const compA = new FakeComponentA; - const compB = new FakeComponentB; + const compA = new FakeComponentA(); + const compB = new FakeComponentB(); const entity1 = new ex.Entity(); entity1.addComponent(compA); entity1.addComponent(compB); @@ -52,8 +52,8 @@ describe('A query', () => { it('can remove entities', () => { const queryAB = new ex.Query([FakeComponentA, FakeComponentB]); - const compA = new FakeComponentA; - const compB = new FakeComponentB; + const compA = new FakeComponentA(); + const compB = new FakeComponentB(); const entity1 = new ex.Entity(); entity1.addComponent(compA); entity1.addComponent(compB); @@ -73,13 +73,13 @@ describe('A query', () => { it('notifies observers of when something is added to the query', (done) => { const queryAB = new ex.Query([FakeComponentA, FakeComponentB]); - const compA = new FakeComponentA; - const compB = new FakeComponentB; + const compA = new FakeComponentA(); + const compB = new FakeComponentB(); const entity1 = new ex.Entity(); entity1.addComponent(compA); entity1.addComponent(compB); - queryAB.entityAdded$.subscribe(e => { + queryAB.entityAdded$.subscribe((e) => { expect(e).toBe(entity1); done(); }); @@ -89,19 +89,18 @@ describe('A query', () => { it('notifies observers of when something is added to the query', (done) => { const queryAB = new ex.Query([FakeComponentA, FakeComponentB]); - const compA = new FakeComponentA; - const compB = new FakeComponentB; + const compA = new FakeComponentA(); + const compB = new FakeComponentB(); const entity1 = new ex.Entity(); entity1.addComponent(compA); entity1.addComponent(compB); queryAB.checkAndAdd(entity1); - queryAB.entityRemoved$.subscribe(e => { + queryAB.entityRemoved$.subscribe((e) => { expect(e).toBe(entity1); done(); }); queryAB.removeEntity(entity1); }); - }); diff --git a/src/spec/RealisticSolverSpec.ts b/src/spec/RealisticSolverSpec.ts index 64cb6e80..0dfbaa3e 100644 --- a/src/spec/RealisticSolverSpec.ts +++ b/src/spec/RealisticSolverSpec.ts @@ -26,14 +26,22 @@ describe('A RealisticSolver', () => { const block = new ex.Actor({ x: 40, y: 0, - width: 40 + .00005, + width: 40 + 0.00005, height: 40, collisionType: ex.CollisionType.Fixed, color: ex.Color.Green }); const contact = new ex.CollisionContact( - player.collider.get(), block.collider.get(), ex.Vector.Down, ex.Vector.Down, ex.Vector.Up.perpendicular(), [], [], null); + player.collider.get(), + block.collider.get(), + ex.Vector.Down, + ex.Vector.Down, + ex.Vector.Up.perpendicular(), + [], + [], + null + ); contact.mtv = ex.vec(-0, 0); @@ -41,5 +49,4 @@ describe('A RealisticSolver', () => { // Considers infinitesimally overlapping to no longer be overlapping and thus cancels the contact expect(contact.isCanceled()).toBe(true); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/ScaleSpec.ts b/src/spec/ScaleSpec.ts index acaea850..90dcc2b2 100644 --- a/src/spec/ScaleSpec.ts +++ b/src/spec/ScaleSpec.ts @@ -12,7 +12,7 @@ describe('A scaled and rotated actor', () => { jasmine.addMatchers(ExcaliburMatchers); jasmine.addAsyncMatchers(ExcaliburAsyncMatchers); - actor = new ex.ScreenElement({x: 50, y:50, width: 100, height: 50}); + actor = new ex.ScreenElement({ x: 50, y: 50, width: 100, height: 50 }); actor.color = ex.Color.Blue; actor.body.collisionType = ex.CollisionType.Active; engine = TestUtils.engine({ width: 800, height: 600 }); @@ -46,10 +46,12 @@ describe('A scaled and rotated actor', () => { clock.step(1); - expectAsync(engine.canvas).toEqualImage('src/spec/images/ScaleSpec/scale.png').then(() => { - done(); - engine.dispose(); - }); + expectAsync(engine.canvas) + .toEqualImage('src/spec/images/ScaleSpec/scale.png') + .then(() => { + done(); + engine.dispose(); + }); }); }); }); diff --git a/src/spec/SceneSpec.ts b/src/spec/SceneSpec.ts index 14b232c3..f0f7f829 100644 --- a/src/spec/SceneSpec.ts +++ b/src/spec/SceneSpec.ts @@ -79,7 +79,7 @@ describe('A scene', () => { scene.clear(); expect(scene.entities.length).withContext('deferred entity removal means entities cleared at end of update').toBe(3); - expect(scene.timers.length).withContext('timers don\'t have deferred removal').toBe(0); + expect(scene.timers.length).withContext("timers don't have deferred removal").toBe(0); scene.update(engine, 100); expect(scene.entities.length).toBe(0); @@ -87,7 +87,7 @@ describe('A scene', () => { }); it('cannot have the same TileMap added to it more than once', () => { - const tileMap = new ex.TileMap({ pos: ex.vec(1, 1), tileWidth: 1, tileHeight: 1, columns: 1, rows: 1}); + const tileMap = new ex.TileMap({ pos: ex.vec(1, 1), tileWidth: 1, tileHeight: 1, columns: 1, rows: 1 }); scene.add(tileMap); expect(scene.tileMaps.length).toBe(1); scene.add(tileMap); @@ -338,7 +338,7 @@ describe('A scene', () => { await engine.goToScene('sceneA'); - await engine.goToScene('sceneB', { sceneActivationData: { foo: 'bar' }}); + await engine.goToScene('sceneB', { sceneActivationData: { foo: 'bar' } }); expect(sceneA.onDeactivate).toHaveBeenCalledWith({ engine, @@ -349,7 +349,7 @@ describe('A scene', () => { engine, previousScene: sceneA, nextScene: sceneB, - data: { foo: 'bar'} + data: { foo: 'bar' } }); }); @@ -564,14 +564,15 @@ describe('A scene', () => { expect(entityAdded).toHaveBeenCalledTimes(1); expect(entityRemoved).toHaveBeenCalledTimes(1); - }); it('can transfer timers', () => { const scene1 = new ex.Scene(); const scene2 = new ex.Scene(); const timer = new ex.Timer({ - fcn: () => { /* pass */ }, + fcn: () => { + /* pass */ + }, interval: 100 }); @@ -716,7 +717,7 @@ describe('A scene', () => { it('will update TileMaps that were added in a Timer callback', () => { let updated = false; - const tilemap = new ex.TileMap({ pos: ex.vec(0, 0), tileWidth: 1, tileHeight: 1, columns: 1, rows: 1}); + const tilemap = new ex.TileMap({ pos: ex.vec(0, 0), tileWidth: 1, tileHeight: 1, columns: 1, rows: 1 }); tilemap._initialize(scene.engine); tilemap.on('postupdate', () => { updated = true; diff --git a/src/spec/ScreenAppenderSpec.ts b/src/spec/ScreenAppenderSpec.ts index 45b57a95..64934b61 100644 --- a/src/spec/ScreenAppenderSpec.ts +++ b/src/spec/ScreenAppenderSpec.ts @@ -12,14 +12,14 @@ describe('A ScreenAppender', () => { }); it('can be constructed', () => { - const engine = TestUtils.engine({width: 100, height: 100}); - const sut = new ex.ScreenAppender({engine}); + const engine = TestUtils.engine({ width: 100, height: 100 }); + const sut = new ex.ScreenAppender({ engine }); expect(sut).toBeDefined(); engine.dispose(); }); it('can be configured to log', async () => { - const engine = TestUtils.engine({width: 100, height: 100}); + const engine = TestUtils.engine({ width: 100, height: 100 }); const sut = new ex.ScreenAppender({ engine, color: ex.Color.Yellow, @@ -43,4 +43,4 @@ describe('A ScreenAppender', () => { // }); engine.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/ScreenElementSpec.ts b/src/spec/ScreenElementSpec.ts index 4724a65b..307b1878 100644 --- a/src/spec/ScreenElementSpec.ts +++ b/src/spec/ScreenElementSpec.ts @@ -31,7 +31,6 @@ describe('A ScreenElement', () => { await TestUtils.runToReady(engine); clock = engine.clock as ex.TestClock; - }); afterEach(() => { @@ -50,14 +49,13 @@ describe('A ScreenElement', () => { }); it('can be constructed with a non-default anchor', () => { - const sut = new ScreenElement({ width: 100, height: 100, - anchor: ex.vec(.5, .5) + anchor: ex.vec(0.5, 0.5) }); - expect(sut.anchor).toBeVector(ex.vec(.5, .5)); + expect(sut.anchor).toBeVector(ex.vec(0.5, 0.5)); expect(sut.collider.get()).toBeInstanceOf(ex.PolygonCollider); expect(sut.collider.get().bounds.width).toBe(100); expect(sut.collider.get().bounds.height).toBe(100); @@ -68,7 +66,6 @@ describe('A ScreenElement', () => { }); it('can be constructed with a non-default collider', () => { - const sut = new ScreenElement({ width: 100, height: 100, @@ -116,7 +113,6 @@ describe('A ScreenElement', () => { expect(screenElement.graphics.onPostDraw).not.toHaveBeenCalled(); }); - it('contains in screen space or world space', () => { screenElement = new ex.ScreenElement({ x: 0, diff --git a/src/spec/ScreenSpec.ts b/src/spec/ScreenSpec.ts index dcf07501..46743855 100644 --- a/src/spec/ScreenSpec.ts +++ b/src/spec/ScreenSpec.ts @@ -170,7 +170,6 @@ describe('A Screen', () => { expect(sut.viewport.heightUnit).toBe('percent'); expect(sut.canvas.offsetWidth).toBe(1300); expect(sut.canvas.offsetHeight).toBe(1300); - }); it('can use the FitContainerAndFill display mode, screen aspectRatio < container aspect ratio', () => { @@ -202,7 +201,6 @@ describe('A Screen', () => { expect(sut.viewport.heightUnit).toBe('percent'); expect(sut.canvas.offsetWidth).toBe(1300); expect(sut.canvas.offsetHeight).toBe(800); - }); it('can use the FitScreenAndZoom display mode, screen aspect ratio < window aspect ratio', () => { @@ -250,7 +248,6 @@ describe('A Screen', () => { }); it('can use the FitContainerAndZoom display mode, screen aspect ratio < container aspect ratio', () => { - const parentEl = document.createElement('div'); document.body.removeChild(canvas); parentEl.appendChild(canvas); @@ -277,7 +274,6 @@ describe('A Screen', () => { }); it('can use the FitContainerAndZoom display mode, screen aspect ratio > container aspect ratio', () => { - const parentEl = document.createElement('div'); document.body.removeChild(canvas); parentEl.appendChild(canvas); @@ -719,7 +715,7 @@ describe('A Screen', () => { sut.setCurrentCamera(camera); sut.applyResolutionAndViewport(); - camera._initialize({screen: sut, clock: { elapsed: () => 16}} as ex.Engine); + camera._initialize({ screen: sut, clock: { elapsed: () => 16 } } as ex.Engine); // The camera is always center screen // The absence of a camera is treated like a camera at (0, 0) in world space @@ -746,7 +742,7 @@ describe('A Screen', () => { sut.setCurrentCamera(camera); sut.applyResolutionAndViewport(); - camera._initialize({screen: sut, clock: { elapsed: () => 16}} as ex.Engine); + camera._initialize({ screen: sut, clock: { elapsed: () => 16 } } as ex.Engine); // The camera is always center screen // The absence of a camera is treated like a camera at (0, 0) in world space @@ -772,7 +768,7 @@ describe('A Screen', () => { sut.setCurrentCamera(camera); sut.applyResolutionAndViewport(); - camera._initialize({screen: sut, clock: { elapsed: () => 16}} as ex.Engine); + camera._initialize({ screen: sut, clock: { elapsed: () => 16 } } as ex.Engine); const bounds = sut.getWorldBounds(); @@ -798,7 +794,7 @@ describe('A Screen', () => { sut.setCurrentCamera(camera); sut.applyResolutionAndViewport(); - camera._initialize({screen: sut, clock: { elapsed: () => 16}} as ex.Engine); + camera._initialize({ screen: sut, clock: { elapsed: () => 16 } } as ex.Engine); const bounds = sut.getWorldBounds(); @@ -897,9 +893,9 @@ describe('A Screen', () => { expect(context.checkIfResolutionSupported).toHaveBeenCalled(); expect(logger.warnOnce).toHaveBeenCalledOnceWith( `The currently configured resolution (${sut.resolution.width}x${sut.resolution.height}) and pixel ratio (${sut.pixelRatio})` + - ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' + - ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' + - ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' + ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' + + ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' + + ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' ); }); @@ -932,15 +928,15 @@ describe('A Screen', () => { expect(context.checkIfResolutionSupported).toHaveBeenCalled(); expect(warnOnce.calls.argsFor(0)).toEqual([ `The currently configured resolution (${sut.resolution.width}x${sut.resolution.height}) and pixel ratio (3)` + - ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' + - ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' + - ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' + ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' + + ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' + + ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' ]); expect(warnOnce.calls.argsFor(1)).toEqual([ 'Scaled resolution too big attempted recovery!' + - ` Pixel ratio was automatically reduced to (2) to avoid 4k texture limit.` + - ' Setting `ex.Engine({pixelRatio: ...}) will override any automatic recalculation, do so at your own risk.` ' + - ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' + ` Pixel ratio was automatically reduced to (2) to avoid 4k texture limit.` + + ' Setting `ex.Engine({pixelRatio: ...}) will override any automatic recalculation, do so at your own risk.` ' + + ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).' ]); }); }); diff --git a/src/spec/SemaphoreSpec.ts b/src/spec/SemaphoreSpec.ts index b5a9d9a2..52218e06 100644 --- a/src/spec/SemaphoreSpec.ts +++ b/src/spec/SemaphoreSpec.ts @@ -35,7 +35,6 @@ describe('A Semaphore', () => { expect(semaphore.waiting).toBe(7); }); - it('can block async calls', (done) => { const mockFuture1 = new ex.Future(); const mockMethod1 = () => { @@ -51,28 +50,31 @@ describe('A Semaphore', () => { const spy1 = jasmine.createSpy(); const spy2 = jasmine.createSpy(); - semaphore.enter().then(() => { - expect(semaphore.count).toBe(0); - expect(semaphore.waiting).toBe(0); - mockMethod1().then(() => { - spy1(); - semaphore.exit(); - }); - const final = semaphore.enter().then(() => { - mockMethod2().then(() => { - spy2(); + semaphore + .enter() + .then(() => { + expect(semaphore.count).toBe(0); + expect(semaphore.waiting).toBe(0); + mockMethod1().then(() => { + spy1(); semaphore.exit(); }); + const final = semaphore.enter().then(() => { + mockMethod2().then(() => { + spy2(); + semaphore.exit(); + }); + }); + expect(semaphore.count).toBe(0); + expect(semaphore.waiting).toBe(1); + return final; + }) + .finally(() => { + expect(spy1).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalled(); + expect(spy1).toHaveBeenCalledBefore(spy2); + done(); }); - expect(semaphore.count).toBe(0); - expect(semaphore.waiting).toBe(1); - return final; - }).finally(() => { - expect(spy1).toHaveBeenCalled(); - expect(spy2).toHaveBeenCalled(); - expect(spy1).toHaveBeenCalledBefore(spy2); - done(); - }); expect(spy1).not.toHaveBeenCalled(); expect(spy2).not.toHaveBeenCalled(); @@ -80,5 +82,4 @@ describe('A Semaphore', () => { mockFuture1.resolve(); mockFuture2.resolve(); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/ShaderSpec.ts b/src/spec/ShaderSpec.ts index b0a1116b..7501e987 100644 --- a/src/spec/ShaderSpec.ts +++ b/src/spec/ShaderSpec.ts @@ -78,7 +78,7 @@ describe('A Shader', () => { }); expect(() => { sut.compile(); - }).toThrowMatching((e:Error) => { + }).toThrowMatching((e: Error) => { return e.message.includes('vertex'); }); }); @@ -99,7 +99,7 @@ describe('A Shader', () => { }); expect(() => { sut.compile(); - }).toThrowMatching((e:Error) => { + }).toThrowMatching((e: Error) => { return e.message.includes('fragment'); }); }); @@ -127,8 +127,9 @@ describe('A Shader', () => { expect(() => { sut.setUniform('uniform1i', 'u_int', 10); - }).toThrowError('Currently accessed shader instance is not the current active shader in WebGL,' - +' must call `shader.use()` before setting uniforms'); + }).toThrowError( + 'Currently accessed shader instance is not the current active shader in WebGL,' + ' must call `shader.use()` before setting uniforms' + ); sut.use(); @@ -181,13 +182,17 @@ describe('A Shader', () => { expect(() => { sut.setUniformFloat('u_doesntexist', 42); - }).toThrowError('Uniform uniform1f:u_doesntexist doesn\'t exist or is not used in the shader source code,' - +' unused uniforms are optimized away by most browsers'); + }).toThrowError( + "Uniform uniform1f:u_doesntexist doesn't exist or is not used in the shader source code," + + ' unused uniforms are optimized away by most browsers' + ); expect(() => { sut.setUniformInt('u_unused', 42); - }).toThrowError('Uniform uniform1i:u_unused doesn\'t exist or is not used in the shader source code,' - +' unused uniforms are optimized away by most browsers'); + }).toThrowError( + "Uniform uniform1i:u_unused doesn't exist or is not used in the shader source code," + + ' unused uniforms are optimized away by most browsers' + ); }); it('can try set uniforms', () => { @@ -222,9 +227,7 @@ describe('A Shader', () => { const loggerSpy = spyOn(logger, 'warn'); sut.trySetUniformInt('u_int', 0); - expect(loggerSpy.calls.argsFor(0)).toEqual([ - 'Must compile shader before setting a uniform uniform1i:u_int' - ]); + expect(loggerSpy.calls.argsFor(0)).toEqual(['Must compile shader before setting a uniform uniform1i:u_int']); sut.compile(); @@ -246,13 +249,17 @@ describe('A Shader', () => { expect(() => { sut.trySetUniformFloat('u_doesntexist', 42); - }).not.toThrowError('Uniform uniform1f:u_doesntexist doesn\'t exist or is not used in the shader source code,' - +' unused uniforms are optimized away by most browsers'); + }).not.toThrowError( + "Uniform uniform1f:u_doesntexist doesn't exist or is not used in the shader source code," + + ' unused uniforms are optimized away by most browsers' + ); expect(() => { sut.trySetUniformInt('u_unused', 42); - }).not.toThrowError('Uniform uniform1i:u_unused doesn\'t exist or is not used in the shader source code,' - +' unused uniforms are optimized away by most browsers'); + }).not.toThrowError( + "Uniform uniform1i:u_unused doesn't exist or is not used in the shader source code," + + ' unused uniforms are optimized away by most browsers' + ); }); it('can have textures set', () => { @@ -281,4 +288,4 @@ describe('A Shader', () => { expect(gl.activeTexture).toHaveBeenCalledWith(gl.TEXTURE0 + 5); expect(gl.bindTexture).toHaveBeenCalledWith(gl.TEXTURE_2D, tex); }); -}); \ No newline at end of file +}); diff --git a/src/spec/SoundSpec.ts b/src/spec/SoundSpec.ts index a8ee3124..5741024c 100644 --- a/src/spec/SoundSpec.ts +++ b/src/spec/SoundSpec.ts @@ -239,7 +239,6 @@ describe('Sound resource', () => { it('should stop all currently playing tracks', (done) => { sut.load().then(() => { - sut.once('playbackstart', () => { expect(sut.isPlaying()).toBe(true, 'track should be playing'); @@ -259,7 +258,7 @@ describe('Sound resource', () => { sut.play(); await delay(1000); // appveyor is a little fast for some reason - expect(sut.getPlaybackPosition()).toBeGreaterThanOrEqual(.98); + expect(sut.getPlaybackPosition()).toBeGreaterThanOrEqual(0.98); }); it('should variable playback rate of the audio track', async () => { @@ -379,7 +378,6 @@ describe('Sound resource', () => { expect(sut.getTotalPlaybackDuration()).toBeCloseTo(13.01, 1); }); - it('can set/get the playback rate', async () => { sut = new ex.Sound('src/spec/images/SoundSpec/preview.ogg'); expect(sut.playbackRate).toBe(1.0); @@ -452,7 +450,6 @@ describe('Sound resource', () => { engine.pauseAudioWhenHidden = true; sut.wireEngine(engine); - sut.once('playbackstart', () => { expect(sut.isPlaying()).withContext('should be playing').toBe(true); diff --git a/src/spec/SpriteSheetSpec.ts b/src/spec/SpriteSheetSpec.ts index 7302e57d..4a576c16 100644 --- a/src/spec/SpriteSheetSpec.ts +++ b/src/spec/SpriteSheetSpec.ts @@ -38,8 +38,8 @@ describe('A SpriteSheet for Graphics', () => { const ss = ex.SpriteSheet.fromImageSourceWithSourceViews({ image, sourceViews: [ - {x: 0, y: 0, width: 20, height: 30}, - {x: 20, y: 0, width: 40, height: 50} + { x: 0, y: 0, width: 20, height: 30 }, + { x: 20, y: 0, width: 40, height: 50 } ] }); @@ -155,7 +155,7 @@ describe('A SpriteSheet for Graphics', () => { flipVertical: true, width: 200, height: 201, - opacity: .5, + opacity: 0.5, scale: ex.vec(2, 2), origin: ex.vec(0, 1), tint: ex.Color.Red, @@ -170,7 +170,7 @@ describe('A SpriteSheet for Graphics', () => { expect(sprite.flipVertical).toBe(true); expect(sprite.width).toBe(400); expect(sprite.height).toBe(402); - expect(sprite.opacity).toBe(.5); + expect(sprite.opacity).toBe(0.5); expect(sprite.scale).toBeVector(ex.vec(2, 2)); expect(sprite.origin).toBeVector(ex.vec(0, 1)); expect(sprite.origin).toBeVector(ex.vec(0, 1)); @@ -191,10 +191,9 @@ describe('A SpriteSheet for Graphics', () => { const clone = ss.clone(); expect(ss).not.toBe(clone); - expect(ss.getSprite(0, 0)).not.toBe(clone.getSprite(0,0)); + expect(ss.getSprite(0, 0)).not.toBe(clone.getSprite(0, 0)); expect(ss.sprites.length).toBe(clone.sprites.length); expect(ss.rows).toBe(clone.rows); expect(ss.columns).toBe(clone.columns); - }); }); diff --git a/src/spec/SpriteSpec.ts b/src/spec/SpriteSpec.ts index 007ef673..af0697f5 100644 --- a/src/spec/SpriteSpec.ts +++ b/src/spec/SpriteSpec.ts @@ -206,8 +206,7 @@ describe('A Sprite Graphic', () => { ctx.flush(); expect(sut.width).toBe(128); expect(sut.height).toBe(128); - await expectAsync(canvasElement) - .toEqualImage('src/spec/images/GraphicsSpriteSpec/change-size-and-scale.png'); + await expectAsync(canvasElement).toEqualImage('src/spec/images/GraphicsSpriteSpec/change-size-and-scale.png'); }); it('can specify a source view of an image by default is same dimension as the source', async () => { @@ -327,7 +326,7 @@ describe('A Sprite Graphic', () => { expect(logger.warnOnce).toHaveBeenCalledWith( `ImageSource path/to/non/existing/image is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\n\n` + - 'Read https://excaliburjs.com/docs/imagesource for more information.' + 'Read https://excaliburjs.com/docs/imagesource for more information.' ); }); }); diff --git a/src/spec/StateMachineSpec.ts b/src/spec/StateMachineSpec.ts index 2b681655..c657b67d 100644 --- a/src/spec/StateMachineSpec.ts +++ b/src/spec/StateMachineSpec.ts @@ -6,7 +6,6 @@ describe('A StateMachine', () => { }); it('can construct a state machine', () => { - const machine = ex.StateMachine.create({ start: 'STOPPED', states: { @@ -30,7 +29,6 @@ describe('A StateMachine', () => { it('will throw on an invalid state machine', () => { expect(() => { - const machine = ex.StateMachine.create({ start: 'STOPPED', states: { @@ -78,7 +76,6 @@ describe('A StateMachine', () => { }); it('can prevent transition onEnter', () => { - const enterSpy = jasmine.createSpy('enter').and.returnValue(false); const exitSpy = jasmine.createSpy('exit').and.returnValue(false); const machine = ex.StateMachine.create({ @@ -106,44 +103,50 @@ describe('A StateMachine', () => { it('can pass data to states', () => { const enterSpy = jasmine.createSpy('enter').and.returnValue(true); const exitSpy = jasmine.createSpy('exit').and.returnValue(true); - const machine = ex.StateMachine.create({ - start: 'PING', - states: { - PING: { - transitions: ['PONG'] - }, - PONG: { - onEnter: enterSpy, - onExit: exitSpy, - transitions: ['PING'] + const machine = ex.StateMachine.create( + { + start: 'PING', + states: { + PING: { + transitions: ['PONG'] + }, + PONG: { + onEnter: enterSpy, + onExit: exitSpy, + transitions: ['PING'] + } } + }, + { + data: 42 } - }, { - data: 42 - }); + ); machine.go('PONG'); - expect(enterSpy).toHaveBeenCalledWith({from: 'PING', eventData: undefined, data: { data: 42 }}); + expect(enterSpy).toHaveBeenCalledWith({ from: 'PING', eventData: undefined, data: { data: 42 } }); machine.go('PING'); - expect(exitSpy).toHaveBeenCalledWith({to: 'PING', data: { data: 42 }}); + expect(exitSpy).toHaveBeenCalledWith({ to: 'PING', data: { data: 42 } }); }); it('can update the current state', () => { const updateSpy = jasmine.createSpy('update').and.returnValue(true); - const machine = ex.StateMachine.create({ - start: 'PING', - states: { - PING: { - transitions: ['PONG'] - }, - PONG: { - onUpdate: updateSpy, - transitions: ['PING'] + const machine = ex.StateMachine.create( + { + start: 'PING', + states: { + PING: { + transitions: ['PONG'] + }, + PONG: { + onUpdate: updateSpy, + transitions: ['PING'] + } } + }, + { + data: 42 } - }, { - data: 42 - }); + ); machine.go('PONG'); machine.update(100); @@ -151,25 +154,28 @@ describe('A StateMachine', () => { }); it('can save a state machine to local storage and restore it with the correct state and data', () => { - const machine = ex.StateMachine.create({ - start: 'PING', - states: { - PING: { - onEnter: ({data}) => { - data.data++; - }, - transitions: ['PONG'] - }, - PONG: { - onEnter: ({data}) => { - data.data++; + const machine = ex.StateMachine.create( + { + start: 'PING', + states: { + PING: { + onEnter: ({ data }) => { + data.data++; + }, + transitions: ['PONG'] }, - transitions: ['PING'] + PONG: { + onEnter: ({ data }) => { + data.data++; + }, + transitions: ['PING'] + } } + }, + { + data: 42 } - }, { - data: 42 - }); + ); machine.go('PONG'); expect(machine.data.data).toBe(43); machine.go('PING'); @@ -179,29 +185,31 @@ describe('A StateMachine', () => { machine.save('my-machine-state'); - const newMachine = ex.StateMachine.create({ - start: 'PING', - states: { - PING: { - onEnter: ({data}) => { - data.data++; - }, - transitions: ['PONG'] - }, - PONG: { - onEnter: ({data}) => { - data.data++; + const newMachine = ex.StateMachine.create( + { + start: 'PING', + states: { + PING: { + onEnter: ({ data }) => { + data.data++; + }, + transitions: ['PONG'] }, - transitions: ['PING'] + PONG: { + onEnter: ({ data }) => { + data.data++; + }, + transitions: ['PING'] + } } + }, + { + data: 42 } - }, { - data: 42 - }); + ); newMachine.restore('my-machine-state'); expect(newMachine.currentState.name).toBe('PONG'); expect(newMachine.data.data).toBe(45); }); }); - diff --git a/src/spec/SystemManagerSpec.ts b/src/spec/SystemManagerSpec.ts index 44d56458..d4e3d651 100644 --- a/src/spec/SystemManagerSpec.ts +++ b/src/spec/SystemManagerSpec.ts @@ -12,7 +12,8 @@ class FakeSystem extends ex.System { public priority: number, public name: string, public types: ex.ComponentCtor[], - public systemType: ex.SystemType) { + public systemType: ex.SystemType + ) { super(); this.query = this.world.query(types); } @@ -91,15 +92,15 @@ describe('A SystemManager', () => { sm.addSystem(system); const e1 = new ex.Entity(); - e1.addComponent(new FakeComponentA); - e1.addComponent(new FakeComponentC); + e1.addComponent(new FakeComponentA()); + e1.addComponent(new FakeComponentC()); const e2 = new ex.Entity(); - e2.addComponent(new FakeComponentB); + e2.addComponent(new FakeComponentB()); const e3 = new ex.Entity(); - e3.addComponent(new FakeComponentC); - e3.addComponent(new FakeComponentA); + e3.addComponent(new FakeComponentC()); + e3.addComponent(new FakeComponentA()); em.addEntity(e1); em.addEntity(e2); diff --git a/src/spec/TagQuerySpec.ts b/src/spec/TagQuerySpec.ts index dc0b47ed..bb706e49 100644 --- a/src/spec/TagQuerySpec.ts +++ b/src/spec/TagQuerySpec.ts @@ -68,7 +68,7 @@ describe('A tag query', () => { entity1.addTag('A'); entity1.addTag('B'); - queryAB.entityAdded$.subscribe(e => { + queryAB.entityAdded$.subscribe((e) => { expect(e).toBe(entity1); done(); }); @@ -83,12 +83,11 @@ describe('A tag query', () => { entity1.addTag('B'); queryAB.checkAndAdd(entity1); - queryAB.entityRemoved$.subscribe(e => { + queryAB.entityRemoved$.subscribe((e) => { expect(e).toBe(entity1); done(); }); queryAB.removeEntity(entity1); }); - }); diff --git a/src/spec/TextSpec.ts b/src/spec/TextSpec.ts index 52acb7e5..3b28f07d 100644 --- a/src/spec/TextSpec.ts +++ b/src/spec/TextSpec.ts @@ -2,7 +2,6 @@ import * as ex from '@excalibur'; import { ExcaliburAsyncMatchers, ExcaliburMatchers } from 'excalibur-jasmine'; import { delay } from '../engine/Util/Util'; - /** * */ @@ -118,7 +117,7 @@ describe('A Text Graphic', () => { }); it('correctly calculates size based on scale', () => { - const sut = new ex.Text({text: 'some text'}); + const sut = new ex.Text({ text: 'some text' }); const currentBounds = sut.localBounds; sut.scale = ex.vec(2, 2); expect(sut.width).toBe(currentBounds.width * 2); @@ -155,7 +154,6 @@ describe('A Text Graphic', () => { }); }); - it('can draw multiple lines of text (font)', async () => { const sut = new ex.Text({ text: 'multiple\nlines\nof text', @@ -315,7 +313,6 @@ describe('A Text Graphic', () => { }); }); - it('can rotate text around the left', async () => { const sut = new ex.Text({ text: 'green text', @@ -544,7 +541,6 @@ describe('A Text Graphic', () => { expect(ex.FontCache.cacheSize).toBe(2); ex.FontCache.clearCache(); expect(ex.FontCache.cacheSize).toBe(0); - }); it('will collect text bitmap garbage', async () => { @@ -726,96 +722,97 @@ describe('A Text Graphic', () => { it('can draw large pieces of text', async () => { const sut = new ex.Text({ - text: 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + - 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + - 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n', + text: + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n' + + 'A long piece of text that is multiple lines needs to be broken into multiple pieces ' + + 'so it can be drawn on mobile devices correctly otherwise it will draw black rectangles on the screen\n', font: new ex.Font({ family: 'Open Sans', size: 18, @@ -846,9 +843,11 @@ describe('A Text Graphic', () => { expect(() => { const text: ex.Text[] = []; for (let i = 0; i < 1000; i++) { - text.push(new ex.Text({ - text: 'text that is long' + i - })); + text.push( + new ex.Text({ + text: 'text that is long' + i + }) + ); } }).not.toThrow(); }); @@ -1001,16 +1000,18 @@ describe('A Text Graphic', () => { sut.draw(ctx, 0, 0); const warnSpy = logger.warnOnce as jasmine.Spy; expect(warnSpy.calls.argsFor(0)).toEqual([ - 'SpriteFont - Cannot find letter \'~\' in configured alphabet \'0123456789abcdefghijklmnopqrstuvwxyz,!\'&."?- \'.']); + "SpriteFont - Cannot find letter '~' in configured alphabet '0123456789abcdefghijklmnopqrstuvwxyz,!'&.\"?- '." + ]); expect(warnSpy.calls.argsFor(1)).toEqual([ - 'There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.']); + 'There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.' + ]); warnSpy.calls.reset(); sut.text = '?'; sut.draw(ctx, 0, 0); - expect(warnSpy.calls.argsFor(0)).toEqual([ - 'SpriteFont - Cannot find sprite for \'?\' at index \'42\' in configured SpriteSheet']); + expect(warnSpy.calls.argsFor(0)).toEqual(["SpriteFont - Cannot find sprite for '?' at index '42' in configured SpriteSheet"]); expect(warnSpy.calls.argsFor(1)).toEqual([ - 'There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.']); + 'There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.' + ]); }); it('can do some simple shadowing', async () => { diff --git a/src/spec/TileMapSpec.ts b/src/spec/TileMapSpec.ts index 715b021d..15f8a73c 100644 --- a/src/spec/TileMapSpec.ts +++ b/src/spec/TileMapSpec.ts @@ -233,7 +233,7 @@ describe('A TileMap', () => { columns: 7 }); const spriteTiles = ex.SpriteSheet.fromImageSource({ - image:texture, + image: texture, grid: { rows: 1, columns: 1, @@ -316,7 +316,7 @@ describe('A TileMap', () => { columns: 20 }); const spriteTiles = ex.SpriteSheet.fromImageSource({ - image:texture, + image: texture, grid: { rows: 1, columns: 1, @@ -349,7 +349,7 @@ describe('A TileMap', () => { }); tm.scale = ex.vec(2, 2); const spriteTiles = ex.SpriteSheet.fromImageSource({ - image:texture, + image: texture, grid: { rows: 1, columns: 1, @@ -479,7 +479,6 @@ describe('A TileMap', () => { columns: 20 }); - const tile = sut.getTile(0, 0); tile.solid = true; @@ -517,12 +516,14 @@ describe('A TileMap', () => { }); const tile = sut.getTile(0, 0); - expect(tile.bounds).toEqual(new ex.BoundingBox({ - left: 100, - top: 100, - right: 164, - bottom: 148 - })); + expect(tile.bounds).toEqual( + new ex.BoundingBox({ + left: 100, + top: 100, + right: 164, + bottom: 148 + }) + ); }); it('can get the center of a tile', () => { @@ -539,7 +540,7 @@ describe('A TileMap', () => { }); it('can respond to pointer events', async () => { - const engine = TestUtils.engine({width: 100, height: 100}); + const engine = TestUtils.engine({ width: 100, height: 100 }); await TestUtils.runToReady(engine); const sut = new ex.TileMap({ pos: ex.vec(100, 100), diff --git a/src/spec/TimerSpec.ts b/src/spec/TimerSpec.ts index ae0e2948..1ba46538 100644 --- a/src/spec/TimerSpec.ts +++ b/src/spec/TimerSpec.ts @@ -485,7 +485,7 @@ describe('A Timer', () => { expect(count).toBe(1); }); - it('can be initialized with random time range', ()=> { + it('can be initialized with random time range', () => { const timer = new ex.Timer({ interval: 100, randomRange: [0, 200] @@ -498,7 +498,7 @@ describe('A Timer', () => { expect(timer.interval).toBeLessThanOrEqual(300); }); - it('has a random interval even with repetition', ()=> { + it('has a random interval even with repetition', () => { const timer = new ex.Timer({ interval: 100, randomRange: [0, 200], @@ -509,23 +509,22 @@ describe('A Timer', () => { timer.update(301); expect(timer.interval).toBeGreaterThanOrEqual(100); expect(timer.interval).toBeLessThanOrEqual(300); - }); - it('an Random instance can be passed, if specified', ()=> { + it('an Random instance can be passed, if specified', () => { const randomMock = jasmine.createSpyObj('Random', ['integer']); randomMock.integer.and.returnValue(11); - const timer = new ex.Timer({ interval: 500, repeats: false, randomRange: [0, 100], random: randomMock}); + const timer = new ex.Timer({ interval: 500, repeats: false, randomRange: [0, 100], random: randomMock }); scene.add(timer); timer.start(); expect(timer.interval).toBe(511); timer.update(511); }); - it('has a randomly set interval with repetition and Random instance passed', ()=> { + it('has a randomly set interval with repetition and Random instance passed', () => { const randomMock = jasmine.createSpyObj('Random', ['integer']); randomMock.integer.and.returnValues(11, 5, 2, 99); - const timer = new ex.Timer({ interval: 500, repeats: true, randomRange: [0, 100], random: randomMock}); + const timer = new ex.Timer({ interval: 500, repeats: true, randomRange: [0, 100], random: randomMock }); scene.add(timer); timer.start(); expect(timer.interval).toBe(511); @@ -537,10 +536,10 @@ describe('A Timer', () => { expect(timer.interval).toBe(599); }); - it('is random after reset with Random instance passed and no repeats are added', ()=> { + it('is random after reset with Random instance passed and no repeats are added', () => { const randomMock = jasmine.createSpyObj('Random', ['integer']); randomMock.integer.and.returnValues(11, 5); - const timer = new ex.Timer({ interval: 500, repeats: false, randomRange: [0, 100], random: randomMock}); + const timer = new ex.Timer({ interval: 500, repeats: false, randomRange: [0, 100], random: randomMock }); scene.add(timer); timer.start(); expect(timer.interval).toBe(511); @@ -551,10 +550,10 @@ describe('A Timer', () => { timer.update(505); }); - it('produces random intervals even with new interval passed during reset', ()=> { + it('produces random intervals even with new interval passed during reset', () => { const randomMock = jasmine.createSpyObj('Random', ['integer']); randomMock.integer.and.returnValues(11, 1, 5); - const timer = new ex.Timer({ interval: 500, repeats: true, randomRange: [0, 100], random: randomMock}); + const timer = new ex.Timer({ interval: 500, repeats: true, randomRange: [0, 100], random: randomMock }); scene.add(timer); timer.start(); expect(timer.interval).toBe(511); @@ -566,4 +565,4 @@ describe('A Timer', () => { expect(timer.interval).toBe(905); timer.update(905); }); -}); \ No newline at end of file +}); diff --git a/src/spec/TimescalingSpec.ts b/src/spec/TimescalingSpec.ts index b4e905e5..2f0ccf01 100644 --- a/src/spec/TimescalingSpec.ts +++ b/src/spec/TimescalingSpec.ts @@ -13,7 +13,7 @@ describe('The engine', () => { scene = new ex.Scene(); engine.add('test', scene); engine.goToScene('test'); - actor = new ex.Actor({x: 0, y: 0, width: 10, height: 10, color: ex.Color.Red}); + actor = new ex.Actor({ x: 0, y: 0, width: 10, height: 10, color: ex.Color.Red }); scene.add(actor); clock = engine.clock as ex.TestClock; await TestUtils.runToReady(engine); diff --git a/src/spec/ToasterSpec.ts b/src/spec/ToasterSpec.ts index 7572bf22..869686d3 100644 --- a/src/spec/ToasterSpec.ts +++ b/src/spec/ToasterSpec.ts @@ -58,7 +58,7 @@ describe('A Toaster', () => { expect(toastContainer.textContent).toContain('Dismiss'); - document.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Escape'})); + document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' })); expect(toastContainer.textContent).not.toContain('Dismiss'); @@ -85,5 +85,4 @@ describe('A Toaster', () => { sut.dispose(); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/TransformComponentSpec.ts b/src/spec/TransformComponentSpec.ts index 43554893..2816af20 100644 --- a/src/spec/TransformComponentSpec.ts +++ b/src/spec/TransformComponentSpec.ts @@ -248,10 +248,10 @@ describe('A TransformComponent', () => { }); it('can be parented/unparented as a TransformComponent', () => { - const child1 = new ex.Entity([new TransformComponent]); - const child2 = new ex.Entity([new TransformComponent]); - const parent = new ex.Entity([new TransformComponent]); - const grandParent = new ex.Entity([new TransformComponent]); + const child1 = new ex.Entity([new TransformComponent()]); + const child2 = new ex.Entity([new TransformComponent()]); + const parent = new ex.Entity([new TransformComponent()]); + const grandParent = new ex.Entity([new TransformComponent()]); parent.addChild(child1); parent.addChild(child2); @@ -270,10 +270,10 @@ describe('A TransformComponent', () => { it('children inherit the top most parent coordinate plane', () => { const logger = ex.Logger.getInstance(); spyOn(logger, 'warn'); - const child1 = new ex.Entity([new TransformComponent]); - const child2 = new ex.Entity([new TransformComponent], 'child2'); - const parent = new ex.Entity([new TransformComponent]); - const grandParent = new ex.Entity([new TransformComponent]); + const child1 = new ex.Entity([new TransformComponent()]); + const child2 = new ex.Entity([new TransformComponent()], 'child2'); + const parent = new ex.Entity([new TransformComponent()]); + const grandParent = new ex.Entity([new TransformComponent()]); parent.addChild(child1); parent.addChild(child2); @@ -299,13 +299,14 @@ describe('A TransformComponent', () => { child2.get(TransformComponent).coordPlane = ex.CoordPlane.World; expect(child2.get(TransformComponent).coordPlane).toBe(ex.CoordPlane.Screen); expect(logger.warn).toHaveBeenCalledWith( - 'Cannot set coordinate plane on child entity child2, children inherit their coordinate plane from their parents.'); + 'Cannot set coordinate plane on child entity child2, children inherit their coordinate plane from their parents.' + ); }); it('can be cloned', () => { const transform = new TransformComponent(); const owner = new ex.Entity([transform]); - transform.pos = ex.vec(1,2); + transform.pos = ex.vec(1, 2); transform.rotation = 3; transform.scale = ex.vec(3, 4); transform.z = 5; diff --git a/src/spec/TransistionSpec.ts b/src/spec/TransistionSpec.ts index 38656a06..5af4731c 100644 --- a/src/spec/TransistionSpec.ts +++ b/src/spec/TransistionSpec.ts @@ -2,7 +2,6 @@ import * as ex from '@excalibur'; import { TestUtils } from './util/TestUtils'; describe('A Transition', () => { - it('exists', () => { expect(ex.Transition).toBeDefined(); }); @@ -30,7 +29,7 @@ describe('A Transition', () => { }); it('can be constructed with defaults', () => { - const sut = new ex.Transition({duration: 2000}); + const sut = new ex.Transition({ duration: 2000 }); expect(sut).toBeTruthy(); expect(sut.name).toContain('Transition#'); expect(sut.duration).toBe(2000); @@ -47,7 +46,7 @@ describe('A Transition', () => { it('can be started with execute()', () => { const engine = TestUtils.engine(); - const sut = new ex.Transition({duration: 3000}); + const sut = new ex.Transition({ duration: 3000 }); const onUpdateSpy = jasmine.createSpy('onUpdate'); const onStartSpy = jasmine.createSpy('onStart'); const onEndSpy = jasmine.createSpy('onEnd'); @@ -56,7 +55,6 @@ describe('A Transition', () => { sut.onEnd = onEndSpy; sut._initialize(engine); - sut.execute(); expect(sut.started).toBe(true); expect(sut.progress).toBe(0); @@ -65,13 +63,13 @@ describe('A Transition', () => { sut.updateTransition(engine, 16); sut.execute(); - expect(onUpdateSpy.calls.argsFor(1)).toEqual([16/3000]); + expect(onUpdateSpy.calls.argsFor(1)).toEqual([16 / 3000]); sut.updateTransition(engine, 16); sut.execute(); - expect(onUpdateSpy.calls.argsFor(2)).toEqual([32/3000]); + expect(onUpdateSpy.calls.argsFor(2)).toEqual([32 / 3000]); - sut.updateTransition(engine, 3200 -32); + sut.updateTransition(engine, 3200 - 32); sut.execute(); expect(onEndSpy).toHaveBeenCalledWith(1); expect(sut.complete).toBe(true); @@ -87,7 +85,7 @@ describe('A Transition', () => { it('can be reset()', () => { const engine = TestUtils.engine(); - const sut = new ex.Transition({duration: 3000}); + const sut = new ex.Transition({ duration: 3000 }); const onUpdateSpy = jasmine.createSpy('onUpdate'); const onStartSpy = jasmine.createSpy('onStart'); const onEndSpy = jasmine.createSpy('onEnd'); @@ -96,7 +94,6 @@ describe('A Transition', () => { sut.onEnd = onEndSpy; sut._initialize(engine); - sut.execute(); expect(sut.started).toBe(true); expect(sut.progress).toBe(0); @@ -105,13 +102,13 @@ describe('A Transition', () => { sut.updateTransition(engine, 16); sut.execute(); - expect(onUpdateSpy.calls.argsFor(1)).toEqual([16/3000]); + expect(onUpdateSpy.calls.argsFor(1)).toEqual([16 / 3000]); sut.updateTransition(engine, 16); sut.execute(); - expect(onUpdateSpy.calls.argsFor(2)).toEqual([32/3000]); + expect(onUpdateSpy.calls.argsFor(2)).toEqual([32 / 3000]); - sut.updateTransition(engine, 3200 -32); + sut.updateTransition(engine, 3200 - 32); sut.execute(); expect(onEndSpy).toHaveBeenCalledWith(1); expect(sut.complete).toBe(true); @@ -129,4 +126,4 @@ describe('A Transition', () => { expect(sut.onReset).toHaveBeenCalledTimes(1); engine.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/spec/UtilSpec.ts b/src/spec/UtilSpec.ts index 087f980e..ddb98976 100644 --- a/src/spec/UtilSpec.ts +++ b/src/spec/UtilSpec.ts @@ -2,9 +2,8 @@ import * as ex from '@excalibur'; import { watchDeep } from '../engine/Util/Watch'; describe('Utility functions', () => { - it('can watch deep', () => { - const deepObject = { + const deepObject = { top: { oneLevel: { twoLevel: { @@ -50,4 +49,4 @@ describe('Utility functions', () => { expect(ex.Util.removeItemFromArray('Lannister', arrayToRemove)).toBe(false); }); }); -}); \ No newline at end of file +}); diff --git a/src/spec/VectorViewSpec.ts b/src/spec/VectorViewSpec.ts index ee77915c..0dfe0938 100644 --- a/src/spec/VectorViewSpec.ts +++ b/src/spec/VectorViewSpec.ts @@ -55,4 +55,4 @@ describe('A VectorView', () => { expect(data[0]).toBe(-1); expect(data[1]).toBe(100); }); -}); \ No newline at end of file +}); diff --git a/src/spec/VertexBufferSpec.ts b/src/spec/VertexBufferSpec.ts index 05c29b89..398ed4f0 100644 --- a/src/spec/VertexBufferSpec.ts +++ b/src/spec/VertexBufferSpec.ts @@ -16,7 +16,6 @@ describe('A VertexBuffer', () => { gl = _ctx.__gl; }); - it('exists', () => { expect(ex.VertexBuffer).toBeDefined(); }); diff --git a/src/spec/VertexLayoutSpec.ts b/src/spec/VertexLayoutSpec.ts index 896aee66..f94d2e4d 100644 --- a/src/spec/VertexLayoutSpec.ts +++ b/src/spec/VertexLayoutSpec.ts @@ -1,4 +1,3 @@ - import * as ex from '@excalibur'; import { ExcaliburMatchers } from 'excalibur-jasmine'; @@ -74,9 +73,7 @@ describe('A VertexLayout', () => { const sut = new ex.VertexLayout({ gl, vertexBuffer, - attributes: [ - ['a_position', 2] - ] + attributes: [['a_position', 2]] }); sut.use(); }).toThrowError('No shader is associated with this vertex layout, a shader must be set'); @@ -107,9 +104,7 @@ describe('A VertexLayout', () => { gl, shader, vertexBuffer, - attributes: [ - ['a_position', 2] - ] + attributes: [['a_position', 2]] }); sut.use(); }).toThrowError('Shader associated with this vertex layout is not active! Call shader.use() before layout.use()'); @@ -139,9 +134,7 @@ describe('A VertexLayout', () => { gl, shader, vertexBuffer, - attributes: [ - ['a_position', 2] - ] + attributes: [['a_position', 2]] }); }).toThrowError('Shader not compiled, shader must be compiled before defining a vertex layout'); }); @@ -171,9 +164,7 @@ describe('A VertexLayout', () => { gl, shader, vertexBuffer, - attributes: [ - ['a_invalid', 2] - ] + attributes: [['a_invalid', 2]] }); }).toThrowMatching((e: Error) => e.message.includes('attribute named: a_invalid size 2 not found')); }); @@ -203,9 +194,7 @@ describe('A VertexLayout', () => { gl, shader, vertexBuffer, - attributes: [ - ['a_position', 4] - ] + attributes: [['a_position', 4]] }); }).toThrowMatching((e: Error) => e.message.includes('VertexLayout size definition for attribute: [a_position, 4]')); }); @@ -261,28 +250,10 @@ describe('A VertexLayout', () => { const uv = shader.attributes.a_uv; expect(createVertexArray).toHaveBeenCalledTimes(1); expect(bindVertexArray).toHaveBeenCalledTimes(2); - expect(vertexAttribPointerSpy.calls.argsFor(0)).toEqual([ - pos.location, - 2, - gl.FLOAT, - false, - 16, - 0 - ]); - expect(enableVertexAttribArraySpy.calls.argsFor(0)).toEqual([ - pos.location - ]); - expect(vertexAttribPointerSpy.calls.argsFor(1)).toEqual([ - uv.location, - 2, - gl.FLOAT, - false, - 16, - 8 - ]); - expect(enableVertexAttribArraySpy.calls.argsFor(1)).toEqual([ - uv.location - ]); + expect(vertexAttribPointerSpy.calls.argsFor(0)).toEqual([pos.location, 2, gl.FLOAT, false, 16, 0]); + expect(enableVertexAttribArraySpy.calls.argsFor(0)).toEqual([pos.location]); + expect(vertexAttribPointerSpy.calls.argsFor(1)).toEqual([uv.location, 2, gl.FLOAT, false, 16, 8]); + expect(enableVertexAttribArraySpy.calls.argsFor(1)).toEqual([uv.location]); expect(gl.vertexAttribPointer).toHaveBeenCalledTimes(2); expect(gl.enableVertexAttribArray).toHaveBeenCalledTimes(2); @@ -323,23 +294,18 @@ describe('A VertexLayout', () => { gl, shader, vertexBuffer: vertexBufferPos, - attributes: [ - ['a_position', 2] - ] + attributes: [['a_position', 2]] }); const sut2 = new ex.VertexLayout({ gl, shader, vertexBuffer: vertexBufferUV, - attributes: [ - ['a_uv', 2] - ] + attributes: [['a_uv', 2]] }); shader.use(); sut1.use(true); sut2.use(true); }); - -}); \ No newline at end of file +}); diff --git a/src/spec/WebGLUtilSpec.ts b/src/spec/WebGLUtilSpec.ts index 15027dac..6291c176 100644 --- a/src/spec/WebGLUtilSpec.ts +++ b/src/spec/WebGLUtilSpec.ts @@ -1,7 +1,6 @@ import * as ex from '@excalibur'; describe('WebGL Util', () => { - it('can return the size of a gl type in bytes', () => { const canvas = document.createElement('canvas'); const context = new ex.ExcaliburGraphicsContextWebGL({ @@ -56,4 +55,4 @@ describe('WebGL Util', () => { expect(ex.webgl.getAttributePointerType(gl, gl.BYTE)).toBe(gl.BYTE); expect(ex.webgl.getAttributePointerType(gl, gl.UNSIGNED_BYTE)).toBe(gl.UNSIGNED_BYTE); }); -}); \ No newline at end of file +}); diff --git a/src/spec/WorldSpec.ts b/src/spec/WorldSpec.ts index 0f1a1c96..a305ba64 100644 --- a/src/spec/WorldSpec.ts +++ b/src/spec/WorldSpec.ts @@ -1,8 +1,7 @@ import * as ex from '@excalibur'; import { SystemType } from '@excalibur'; -class FakeComponent extends ex.Component { -} +class FakeComponent extends ex.Component {} class FakeSystem extends ex.System { public systemType = ex.SystemType.Update; query: ex.Query; @@ -80,10 +79,14 @@ describe('A World', () => { }); it('can update', () => { - const scene = new ex.Scene; + const scene = new ex.Scene(); const world = new ex.World(scene); - world.entityManager = jasmine.createSpyObj('EntityManager', - ['processEntityRemovals', 'findEntitiesForRemoval', 'processComponentRemovals', 'updateEntities']); + world.entityManager = jasmine.createSpyObj('EntityManager', [ + 'processEntityRemovals', + 'findEntitiesForRemoval', + 'processComponentRemovals', + 'updateEntities' + ]); world.systemManager = jasmine.createSpyObj('SystemManager', ['updateSystems']); world.update(SystemType.Update, 100); diff --git a/src/spec/_boot.ts b/src/spec/_boot.ts index 8ec9accb..9ff6ceba 100644 --- a/src/spec/_boot.ts +++ b/src/spec/_boot.ts @@ -10,26 +10,25 @@ window.devicePixelRatio = 1; const MemoryReporter = { previousMemory: (window.performance as any).memory, largeMemory: [], - jasmineStarted: function(suiteInfo) { + jasmineStarted: function (suiteInfo) { this.previousMemory = (window.performance as any).memory; }, - - specDone: function(result) { + specDone: function (result) { const currentMemory = (window.performance as any).memory; - const megabytes = (currentMemory.usedJSHeapSize - this.previousMemory.usedJSHeapSize) * 0.000001; + const megabytes = (currentMemory.usedJSHeapSize - this.previousMemory.usedJSHeapSize) * 0.000001; if (megabytes > 1) { const message = `Spec ${result.fullName} MB: ${megabytes}`; - this.largeMemory.push({size: megabytes, message}); + this.largeMemory.push({ size: megabytes, message }); } this.previousMemory = currentMemory; }, - jasmineDone: function(result) { + jasmineDone: function (result) { this.largeMemory.sort((a, b) => { return b.size - a.size; }); - for (const test of this.largeMemory.slice(0, 20)){ + for (const test of this.largeMemory.slice(0, 20)) { console.log(test.message); // eslint-disable-line } } @@ -38,7 +37,7 @@ const MemoryReporter = { const EngineReporter = { currentEngines: ex.Engine.InstanceCount, leaks: [], - specDone: function(result) { + specDone: function (result) { if (this.currentEngines < ex.Engine.InstanceCount) { // const message = `Spec ${result.fullName} Engine increased: ${ex.Engine.InstanceCount}`; // console.log(message); @@ -47,9 +46,9 @@ const EngineReporter = { this.currentEngines = ex.Engine.InstanceCount; }, - jasmineDone: function(result) { + jasmineDone: function (result) { let leakString = '============ Engine leaks ==================\n'; - for (const leak of this.leaks){ + for (const leak of this.leaks) { leakString += leak + '\n'; } console.log(leakString); // eslint-disable-line @@ -58,7 +57,7 @@ const EngineReporter = { const TimeoutSpecReporter = { specs: {}, - specStarted: function(result) { + specStarted: function (result) { this.specs[result.fullName] = Date.now(); setTimeout(() => { if (this.specs[result.fullName]) { @@ -66,7 +65,7 @@ const TimeoutSpecReporter = { } }, 5000); }, - specDone: function(result) { + specDone: function (result) { delete this.specs[result.fullName]; } }; @@ -74,4 +73,3 @@ const TimeoutSpecReporter = { // jasmine.getEnv().addReporter(MemoryReporter); jasmine.getEnv().addReporter(TimeoutSpecReporter); jasmine.getEnv().addReporter(EngineReporter); - diff --git a/src/spec/images/GraphicsTextSpec/fonts.css b/src/spec/images/GraphicsTextSpec/fonts.css index e61f92ff..9e5a1b91 100644 --- a/src/spec/images/GraphicsTextSpec/fonts.css +++ b/src/spec/images/GraphicsTextSpec/fonts.css @@ -1,4 +1,3 @@ - /* latin */ @font-face { font-family: 'Open Sans'; @@ -6,7 +5,8 @@ font-weight: 400; font-display: swap; src: url(./fonts/italic-400.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; } /* latin */ @@ -16,7 +16,8 @@ font-weight: 600; font-display: swap; src: url(./fonts/italic-600.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; } /* latin */ @@ -26,7 +27,8 @@ font-weight: 700; font-display: swap; src: url(./fonts/italic-700.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; } /* latin */ @@ -36,7 +38,8 @@ font-weight: 800; font-display: swap; src: url(./fonts/italic-800.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; } /* latin */ @@ -46,7 +49,8 @@ font-weight: 400; font-display: swap; src: url(./fonts/normal-400.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; } /* latin */ @@ -56,7 +60,8 @@ font-weight: 600; font-display: swap; src: url(./fonts/normal-600.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; } /* latin */ @@ -66,7 +71,8 @@ font-weight: 700; font-display: swap; src: url(./fonts/normal-700.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; } /* latin */ @@ -76,5 +82,6 @@ font-weight: 800; font-display: swap; src: url(./fonts/normal-800.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} \ No newline at end of file + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/src/spec/util/TestUtils.ts b/src/spec/util/TestUtils.ts index 17e1ee89..713e9aa1 100644 --- a/src/spec/util/TestUtils.ts +++ b/src/spec/util/TestUtils.ts @@ -5,8 +5,7 @@ export namespace TestUtils { * Builds an engine with testing switches on * @param options */ - export function engine(options: ex.EngineOptions = {}, flags: string[] = [ - 'suppress-obsolete-message']): ex.Engine { + export function engine(options: ex.EngineOptions = {}, flags: string[] = ['suppress-obsolete-message']): ex.Engine { options = { width: 500, height: 500, @@ -23,7 +22,7 @@ export namespace TestUtils { ex.Debug.clear(); ex.Flags._reset(); ex.Flags.enable('suppress-obsolete-message'); - flags.forEach(f => ex.Flags.enable(f)); + flags.forEach((f) => ex.Flags.enable(f)); const game = new ex.Engine(options); // keeps the pointer based tests consistent @@ -64,7 +63,7 @@ export namespace TestUtils { * */ export async function flushMicrotasks(clock: ex.TestClock, times: number) { - for ( let i = 0; i < times; i++) { + for (let i = 0; i < times; i++) { clock.step(0); await Promise.resolve(); } diff --git a/src/stories/Anchors.stories.ts b/src/stories/Anchors.stories.ts index 8c0f34c0..71bc912f 100644 --- a/src/stories/Anchors.stories.ts +++ b/src/stories/Anchors.stories.ts @@ -131,7 +131,7 @@ export const TopLeft: StoryObj = { }) }; -export const topRight: StoryObj = { +export const TopRight: StoryObj = { render: withEngine(async (game) => { const heartTx = new ImageSource(heartBitmap); const ldr = new Loader([heartTx]); diff --git a/src/stories/ParticleEmitter.stories.ts b/src/stories/ParticleEmitter.stories.ts index 45aff3fb..3b4a42de 100644 --- a/src/stories/ParticleEmitter.stories.ts +++ b/src/stories/ParticleEmitter.stories.ts @@ -7,63 +7,68 @@ export default { } as Meta; export const Main: StoryObj = { - render: withEngine(async (game, { - width, - height, - emitterType, - radius, - minVel, - maxVel, - minAngle, - maxAngle, - isEmitting, - emitRate, - opacity, - fadeFlag, - particleLife, - minSize, - maxSize, - startSize, - endSize, - accelX, - accelY, - beginColor, - endColor - }) => { - // Default Scenario - game.backgroundColor = Color.Black; + render: withEngine( + async ( + game, + { + width, + height, + emitterType, + radius, + minVel, + maxVel, + minAngle, + maxAngle, + isEmitting, + emitRate, + opacity, + fadeFlag, + particleLife, + minSize, + maxSize, + startSize, + endSize, + accelX, + accelY, + beginColor, + endColor + } + ) => { + // Default Scenario + game.backgroundColor = Color.Black; - // Particle Emitter - const emitter = new ParticleEmitter({ - x: game.currentScene.camera.x, - y: game.currentScene.camera.y, - width, - height, - emitterType, - radius, - minVel, - maxVel, - minAngle, - maxAngle, - isEmitting, - emitRate, - opacity, - fadeFlag, - particleLife, - minSize, - maxSize, - startSize, - endSize, - acceleration: new Vector(accelX, accelY), - beginColor: Color.fromRGBString(beginColor), - endColor: Color.fromRGBString(endColor), - focusAccel: 800 - }); + // Particle Emitter + const emitter = new ParticleEmitter({ + x: game.currentScene.camera.x, + y: game.currentScene.camera.y, + width, + height, + emitterType, + radius, + minVel, + maxVel, + minAngle, + maxAngle, + isEmitting, + emitRate, + opacity, + fadeFlag, + particleLife, + minSize, + maxSize, + startSize, + endSize, + acceleration: new Vector(accelX, accelY), + beginColor: Color.fromRGBString(beginColor), + endColor: Color.fromRGBString(endColor), + focusAccel: 800 + }); - game.add(emitter); + game.add(emitter); - await game.start(); - }), + await game.start(); + } + ), argTypes: { width: { control: { type: 'number', range: true, min: 0, max: 100, step: 1 } }, height: { control: { type: 'number', range: true, min: 0, max: 100, step: 1 } }, @@ -110,4 +115,4 @@ export const Main: StoryObj = { beginColor: Color.Rose.toRGBA(), endColor: Color.Yellow.toRGBA() } -}; \ No newline at end of file +}; diff --git a/src/stories/globals.d.ts b/src/stories/globals.d.ts index b3d725f7..5c1c18f6 100644 --- a/src/stories/globals.d.ts +++ b/src/stories/globals.d.ts @@ -1 +1 @@ -declare module '*.md'; \ No newline at end of file +declare module '*.md'; diff --git a/src/stories/utils.ts b/src/stories/utils.ts index 158643a8..b23e51ab 100644 --- a/src/stories/utils.ts +++ b/src/stories/utils.ts @@ -51,7 +51,7 @@ export const withEngine = (storyFn: (game: Engine, args?: Record) = ...options }); - Logger.getInstance().info('Press \'d\' for debug mode'); + Logger.getInstance().info("Press 'd' for debug mode"); game.input.keyboard.on('down', (keyDown?: KeyEvent) => { if (keyDown.key === Keys.D) { diff --git a/version.js b/version.js index 2510c950..5b18d495 100644 --- a/version.js +++ b/version.js @@ -20,11 +20,11 @@ function getAlphaVersion() { } } -function getReleaseVersion() { +function getReleaseVersion() { return package.version; } module.exports = { getAlphaVersion: getAlphaVersion, getReleaseVersion: getReleaseVersion -} \ No newline at end of file +}; diff --git a/wallaby.js b/wallaby.js index 8fcda585..8aae9e11 100644 --- a/wallaby.js +++ b/wallaby.js @@ -34,7 +34,7 @@ module.exports = function (wallaby) { mode: 'none', devtool: 'source-map', optimization: { - providedExports: true, + providedExports: true }, resolve: { extensions: ['.ts', '.js'], diff --git a/webpack.config.js b/webpack.config.js index 226a8683..258da3a1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -47,8 +47,8 @@ module.exports = (env, argv) => { experiments: env.output === 'esm' ? { - outputModule: true - } + outputModule: true + } : {}, resolve: { // Add `.ts` and `.tsx` as a resolvable extension. @@ -100,5 +100,5 @@ Licensed ${pkg.license} @preserve` ) ] - } + }; };