diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index e42dd230a3..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -# Similar to .gitignore, this lists files ignored by eslint. - -# This is default ignored, but we want to still lint it. -!.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 2423eddb7a..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,312 +0,0 @@ -// vim: foldmethod=marker:foldmarker={{{,}}} -/*! @license - * Shaka Player - * Copyright 2016 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -// ESlint config - -// This is a matcher (usable in no-restricted-syntax) that matches either a -// test or a before/after block. -const testNameRegex = - '/^([fx]?it|(drm|quarantined)It|(before|after)(Each|All))$/'; -const testCall = `CallExpression[callee.name=${testNameRegex}]`; - -const commonNoRestrictedSyntax = [ - { - 'selector': - 'MemberExpression[object.name="goog"][property.name="inherits"]', - 'message': 'Don\'t use goog.inherits.', - }, - { - 'selector': ':not(MethodDefinition) > FunctionExpression', - 'message': 'Use arrow functions instead of "function" functions.', - }, - { - 'selector': 'CallExpression[callee.property.name="forEach"] >' + - ':function[params.length=1]', - 'message': 'Use for-of instead of forEach', - }, - { - // NOTE: prefer-spread rule covers .apply() already. - 'selector': 'CallExpression[callee.property.name=/^(bind|call)$/]', - 'message': 'Don\'t use Function bind/call.', - }, - { - 'selector': 'MemberExpression[property.name="prototype"]', - 'message': 'Use ES6 classes not .prototype.', - }, - { - 'selector': 'BinaryExpression[operator=/^([<>!=]=?)$/] > ' + - 'CallExpression[callee.property.name=indexOf]', - 'message': 'Use Array.includes instead of indexOf.', - }, -]; - -module.exports = { - 'env': { - 'browser': true, - 'es6': true, - }, - 'parserOptions': { - 'ecmaVersion': 2017, - }, - 'extends': ['eslint:recommended', 'google', 'plugin:shaka-rules/config'], - 'rules': { - // Things the compiler already takes care of, with more precision: {{{ - 'no-console': 'off', - 'no-eq-null': 'off', - 'no-eval': 'off', - 'no-undef': 'off', - 'valid-jsdoc': 'off', - // }}} - - // Things we should probably fix, but in stages in multiple commits: {{{ - - // These could catch real bugs - 'default-case': 'off', - // TODO: Enable no-loop-func in next eslint release. We can't use it - // now since it doesn't allow capturing "const" variables, which is safe - 'no-loop-func': 'off', - 'no-unused-expressions': 'off', // Conflicts with some Closure declarations - 'prefer-promise-reject-errors': 'off', - - // These could improve readability - 'complexity': 'off', - 'no-negated-condition': 'off', - 'no-shadow': 'off', - // }}} - - // "Possible error" rules: {{{ - 'no-async-promise-executor': 'error', - 'no-await-in-loop': 'error', - 'no-empty': ['error', {'allowEmptyCatch': true}], - 'no-misleading-character-class': 'error', - 'no-template-curly-in-string': 'error', - 'no-fallthrough': ['error', {'allowEmptyCase': true}], - // TODO: Try to re-enable this if possible. Right now, it produces way too - // many false-positives with eslint 7. It worked well enough in eslint 5. - // 'require-atomic-updates': 'error', - // }}} - - // "Best practices" rules: {{{ - 'accessor-pairs': 'error', - 'array-callback-return': 'error', - // causes issues when implementing an interface - 'class-methods-use-this': 'off', - 'consistent-return': 'error', - 'dot-location': ['error', 'property'], - 'dot-notation': 'off', // We use bracket notation in tests on purpose - 'eqeqeq': 'off', // Compiler handles type checking in advance - 'guard-for-in': 'off', - 'no-alert': 'error', - 'no-caller': 'error', - 'no-div-regex': 'error', - 'no-extend-native': 'error', // May conflict with future polyfills - 'no-extra-label': 'error', - 'no-floating-decimal': 'error', - 'no-implicit-coercion': ['error', {'allow': ['!!']}], - 'no-implied-eval': 'error', - 'no-invalid-this': 'error', - 'no-iterator': 'error', - 'no-labels': 'error', - 'no-lone-blocks': 'error', - 'no-multi-spaces': ['error', {'ignoreEOLComments': true}], - 'no-multi-str': 'error', - 'no-new': 'error', - 'no-new-func': 'error', - 'no-new-wrappers': 'error', - 'no-octal-escape': 'error', - 'no-proto': 'error', - 'no-return-assign': 'error', - 'no-return-await': 'error', - 'no-script-url': 'error', - 'no-self-compare': 'error', - 'no-sequences': 'error', - 'no-throw-literal': 'error', - 'no-unmodified-loop-condition': 'error', - // Interface implementations may not require all args - 'no-unused-vars': 'off', - 'no-useless-call': 'error', - 'no-useless-catch': 'error', - 'no-useless-concat': 'error', - 'no-useless-return': 'error', - 'no-void': 'error', - 'no-warning-comments': 'off', // TODO and FIXME are fine - 'radix': ['error', 'always'], - 'require-await': 'error', - 'wrap-iife': ['error', 'inside'], - 'yoda': ['error', 'never'], - // }}} - - // "Variables" rules: {{{ - 'no-label-var': 'error', - 'no-shadow-restricted-names': 'error', - 'no-undef-init': 'off', // Sometimes necessary with hacky compiler casts - 'no-undefined': 'off', // We use undefined in many places, legitimately - // Does not know when things are executed, false positives - 'no-use-before-define': 'off', - // }}} - - // "Stylistic Issues" rules: {{{ - 'array-bracket-newline': ['error', 'consistent'], - 'block-spacing': ['error', 'always'], - 'brace-style': ['error', '1tbs', {'allowSingleLine': true}], - 'id-denylist': ['error', 'async'], - 'lines-between-class-members': 'error', - 'max-statements-per-line': ['error', {'max': 1}], - 'new-parens': 'error', - 'no-mixed-operators': [ - 'error', { - 'groups': [['&', '|', '^', '~', '<<', '>>', '>>>', '&&', '||']], - 'allowSamePrecedence': false, - }, - ], - 'no-restricted-syntax': [ - 'error', - ...commonNoRestrictedSyntax, - ], - 'no-whitespace-before-property': 'error', - // cspell: disable-next-line - 'nonblock-statement-body-position': ['error', 'below'], - 'operator-assignment': 'error', - 'spaced-comment': ['error', 'always', { - // Characters which may be glued to the start of a comment block, but - // which do not violate the rule. The "*" is for jsdoc's "/**" syntax, - // and the "!" is for the "/*!" of license headers which are passed - // verbatim through the compiler. - 'markers': ['*', '!'], - }], - 'require-jsdoc': ['error', { - 'require': { - 'FunctionDeclaration': true, - 'MethodDefinition': true, - 'ClassDeclaration': true, - }, - }], - // }}} - - // "ECMAScript 6" rules: {{{ - 'arrow-spacing': 'error', - 'no-useless-constructor': 'error', - 'prefer-arrow-callback': 'error', - 'prefer-const': ['error', {'ignoreReadBeforeAssign': true}], - // }}} - }, - 'overrides': [ - { - 'rules': { - 'no-restricted-syntax': [ - 'error', - { - 'selector': 'CallExpression[callee.name="beforeAll"] ' + - ':matches(' + - 'CallExpression[callee.property.name="createSpy"],' + - 'CallExpression[callee.name="spyOn"])', - 'message': 'Create spies in beforeEach, not beforeAll.', - }, - { - 'selector': testCall + ' > :function[params.length>0]', - 'message': 'Use async instead of "done" in tests.', - }, - { - 'selector': testCall + ' > CallExpression', - 'message': 'Use filterDescribe instead of checkAndRun calls', - }, - { - 'selector': 'CatchClause', - 'message': 'Use expect.toThrow or expectAsync.toBeRejected', - }, - { - 'selector': 'CallExpression[callee.name=expect] >' + - 'CallExpression[callee.property.name=count]' + - '[callee.object.property.name=calls]', - 'message': 'Use expect.toHaveBeenCalledTimes', - }, - { - 'selector': - 'CallExpression[callee.property.name=toHaveBeenCalledTimes] >' + - 'Literal[value=0]', - 'message': 'Use expect.not.toHaveBeenCalled', - }, - ...commonNoRestrictedSyntax, - ], - }, - 'files': [ - 'test/**/*.js', - ], - }, - { - 'rules': { - 'no-restricted-syntax': 'off', - }, - 'files': [ - 'demo/load.js', - 'externs/**/*.js', - 'test/test/externs/*.js', - 'ui/externs/*.js', - ], - }, - { - 'rules': { - 'no-var': 'off', - }, - 'files': [ - // Closure requires using var in externs. - 'ui/externs/*.js', - 'externs/**/*.js', - 'test/test/externs/*.js', - // Use var in load.js so it works in old browsers. We'll use - // compiled mode for the main library and the demo. - 'demo/load.js', - ], - }, - { - 'rules': { - 'prefer-rest-params': 'off', - }, - 'files': [ - // Test code should still use "arguments", since the alternate - // "rest parameter" syntax won't work in uncompiled code on IE. - 'test/**/*.js', - // These two files use "arguments" to patch over functions. It - // is difficult to reason about whether or not these instances - // would always work with rest parameters, so just allow them to - // use "arguments". - 'demo/log_section.js', - 'lib/debug/asserts.js', - ], - }, - { - 'rules': { - // Disable rules on useless constructors so we can use ES6 classes in - // externs. - 'no-useless-constructor': 'off', - }, - 'files': ['externs/**/*.js'], - }, - { - 'rules': { - // JSDoc is not strictly required in externs, tests, and in load.js. - 'require-jsdoc': 'off', - }, - 'files': [ - 'demo/load.js', - 'externs/**/*.js', - 'test/**/*.js', - ], - }, - { - 'rules': { - // Externs naturally redeclare things eslint knows about. - 'no-redeclare': 'off', - }, - 'files': [ - 'ui/externs/*.js', - 'externs/**/*.js', - 'test/test/externs/*.js', - ], - }, - ], -}; diff --git a/.gitattributes b/.gitattributes index a1f64a4556..ccdfa0cc00 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.sh text eol=lf *.py text eol=lf *.js text eol=lf +*.mjs text eol=lf diff --git a/.github/workflows/demo-version-index.yaml b/.github/workflows/demo-version-index.yaml index 399c246b17..f46681508b 100644 --- a/.github/workflows/demo-version-index.yaml +++ b/.github/workflows/demo-version-index.yaml @@ -3,20 +3,19 @@ name: Deploy Demo Version Index on: workflow_dispatch: # Allows for manual triggering. + workflow_call: + # Allows calling this from another workflow with "uses:". + # The release workflow will trigger this as a final step after updating the + # appspot deployment. + secrets: + APPENGINE_DEPLOY_KEY: + required: true push: branches: - main paths: - .github/workflows/demo-version-index.yaml - app-engine/demo-version-index/** - release: - types: [published] - # NOTE: So long as releases are made without a personal access token (PAT), - # they will not activate this workflow's release trigger. For now, the - # schedule trigger will compensate for that by updating the index nightly. - schedule: - # Run every night at 10pm PST / 6am UTC. - - cron: '0 6 * * *' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/nightly-demo.yaml b/.github/workflows/nightly-demo.yaml index 9968931d60..8e62e97217 100644 --- a/.github/workflows/nightly-demo.yaml +++ b/.github/workflows/nightly-demo.yaml @@ -25,14 +25,6 @@ jobs: node-version: 22 registry-url: 'https://registry.npmjs.org' - # The nightly demo has its own receiver app ID that points to the nightly - # demo itself for the receiver side. - - name: Override Cast Receiver App ID - run: | - sed \ - -i demo/index.html \ - -e 's/\(data-shaka-player-cast-receiver-id\)="[^"]*"/\1="07AEE832"/' - - uses: ./.github/workflows/custom-actions/prep-for-appspot - uses: google-github-actions/auth@v2 diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml index cb775154ee..c9cde4fa85 100644 --- a/.github/workflows/release-please.yaml +++ b/.github/workflows/release-please.yaml @@ -202,3 +202,10 @@ jobs: TAG=${{ needs.release.outputs.tag_name }} BRANCH=$(echo "$TAG" | sed -e 's/\.0$/.x/') git push origin refs/tags/"$TAG"^{commit}:refs/heads/"$BRANCH" + + update-demo-index: + name: Deploy Demo Version Index + needs: [appspot] + uses: ./.github/workflows/demo-version-index.yaml + secrets: + APPENGINE_DEPLOY_KEY: '${{ secrets.APPENGINE_DEPLOY_KEY }}' diff --git a/build/check.py b/build/check.py index 424068bdc0..898bc7ad10 100755 --- a/build/check.py +++ b/build/check.py @@ -68,7 +68,7 @@ def get_lint_files(): get('build')) main_sources.remove(os.path.join(base, 'build', 'wrapper.template.js')) tool_sources = [ - os.path.join(base, '.eslintrc.js'), + os.path.join(base, 'eslint.config.mjs'), os.path.join(base, 'docs', 'jsdoc-plugin.js'), os.path.join(base, 'karma.conf.js'), ] @@ -82,7 +82,7 @@ def check_js_lint(args): logging.info('Linting JavaScript...') base = shakaBuildHelpers.get_source_base() - config_path = os.path.join(base, '.eslintrc.js') + config_path = os.path.join(base, 'eslint.config.mjs') linter = compiler.Linter(get_lint_files(), config_path) return linter.lint(fix=args.fix, force=args.force) diff --git a/build/eslint-plugin-shaka-rules/arg-comment-spacing.js b/build/eslint-plugin-shaka-rules/arg-comment-spacing.js index 0fcade47c0..79f2b0d531 100644 --- a/build/eslint-plugin-shaka-rules/arg-comment-spacing.js +++ b/build/eslint-plugin-shaka-rules/arg-comment-spacing.js @@ -4,9 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -const assert = require('assert'); - -module.exports = { +export default { meta: { type: 'suggestion', docs: { diff --git a/build/eslint-plugin-shaka-rules/array-no-instanceof.js b/build/eslint-plugin-shaka-rules/array-no-instanceof.js index 493d6dafb2..275c924e0d 100644 --- a/build/eslint-plugin-shaka-rules/array-no-instanceof.js +++ b/build/eslint-plugin-shaka-rules/array-no-instanceof.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -module.exports = { +export default { meta: { type: 'suggestion', docs: { diff --git a/build/eslint-plugin-shaka-rules/buffersource-no-instanceof.js b/build/eslint-plugin-shaka-rules/buffersource-no-instanceof.js index 1d39054a3e..0fd6635f77 100644 --- a/build/eslint-plugin-shaka-rules/buffersource-no-instanceof.js +++ b/build/eslint-plugin-shaka-rules/buffersource-no-instanceof.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -module.exports = { +export default { meta: { type: 'suggestion', docs: { diff --git a/build/eslint-plugin-shaka-rules/index.js b/build/eslint-plugin-shaka-rules/index.js index 3f5781cbcf..c12eef8e62 100644 --- a/build/eslint-plugin-shaka-rules/index.js +++ b/build/eslint-plugin-shaka-rules/index.js @@ -4,23 +4,30 @@ * SPDX-License-Identifier: Apache-2.0 */ -module.exports = { - rules: {}, +import argCommentSpacing from './arg-comment-spacing.js'; +import arrayNoInstanceof from './array-no-instanceof.js'; +import buffersourceNoInstanceof from './buffersource-no-instanceof.js'; +import privateRule from './private.js'; + +const index = { + rules: { + 'arg-comment-spacing': argCommentSpacing, + 'array-no-instanceof': arrayNoInstanceof, + 'buffersource-no-instanceof': buffersourceNoInstanceof, + 'private': privateRule, + }, configs: { config: { - plugins: ['shaka-rules'], + plugins: {}, rules: {}, }, }, }; -const RULES = [ - 'arg-comment-spacing', - 'array-no-instanceof', - 'buffersource-no-instanceof', - 'private', -]; -for (const rule of RULES) { - module.exports.rules[rule] = require('./' + rule); - module.exports.configs.config.rules['shaka-rules/' + rule] = 'error'; +index.configs.config.plugins['shaka-rules'] = index; + +for (const rule of Object.keys(index.rules)) { + index.configs.config.rules['shaka-rules/' + rule] = 'error'; } + +export default index; diff --git a/build/eslint-plugin-shaka-rules/package.json b/build/eslint-plugin-shaka-rules/package.json index 81b478294e..258a59c24f 100644 --- a/build/eslint-plugin-shaka-rules/package.json +++ b/build/eslint-plugin-shaka-rules/package.json @@ -3,5 +3,6 @@ "description": "Extra eslint rules for Shaka Player", "version": "0.0.1", "main": "index.js", + "type": "module", "private": true } diff --git a/build/eslint-plugin-shaka-rules/private.js b/build/eslint-plugin-shaka-rules/private.js index f15c44c52b..612bff5437 100644 --- a/build/eslint-plugin-shaka-rules/private.js +++ b/build/eslint-plugin-shaka-rules/private.js @@ -4,9 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -const assert = require('assert'); +import assert from 'assert'; -module.exports = { +export default { meta: { type: 'suggestion', docs: { diff --git a/build/generateExterns.js b/build/generateExterns.js index 39cb332945..4cfdcabc2c 100755 --- a/build/generateExterns.js +++ b/build/generateExterns.js @@ -315,7 +315,7 @@ function getFunctionParameters(node) { * Take the original block comment and prep it for the externs by removing * export annotations and blank lines. * - * @param {string} + * @param {string} comment * @return {string} */ function removeExportAnnotationsFromComment(comment) { @@ -498,7 +498,7 @@ function createExternMethod(node) { /** * Find the constructor of an ES6 class, if it exists. * - * @param {ASTNode} className + * @param {ASTNode} classNode * @return {ASTNode} */ function getClassConstructor(classNode) { diff --git a/demo/common/asset.js b/demo/common/asset.js index ca05dab5c5..c0655ac58a 100644 --- a/demo/common/asset.js +++ b/demo/common/asset.js @@ -428,10 +428,9 @@ const ShakaDemoAssetInfo = class { /** * @return {!Object} * @override - * + * @suppress {checkTypes} * Suppress checkTypes warnings, so that we can access properties of this * object as though it were a struct. - * @suppress {checkTypes} */ toJSON() { // Construct a generic object with the values of this object, but with the diff --git a/demo/custom.js b/demo/custom.js index 764f8e92eb..c543b632f1 100644 --- a/demo/custom.js +++ b/demo/custom.js @@ -894,6 +894,7 @@ shakaDemo.Custom = class { /** * @param {!ShakaDemoAssetInfo} assetInProgress + * @return {boolean} * @private */ checkManifestRequired_(assetInProgress) { diff --git a/demo/input.js b/demo/input.js index 9676a9a29a..607a13439d 100644 --- a/demo/input.js +++ b/demo/input.js @@ -98,10 +98,10 @@ shakaDemo.Input = class { } /** - * @param {string} prefix - * @return {string} - * @private - */ + * @param {string} prefix + * @return {string} + * @private + */ static generateNewId_(prefix) { const idNumber = shakaDemo.Input.lastId_; shakaDemo.Input.lastId_ += 1; diff --git a/demo/main.js b/demo/main.js index 333d364e15..4e2d3b737b 100644 --- a/demo/main.js +++ b/demo/main.js @@ -1483,7 +1483,7 @@ shakaDemo.Main = class { goog.asserts.assert(this.video_ != null, 'this.video should exist!'); adManager.initClientSide( this.controls_.getClientSideAdContainer(), this.video_, - /** adsRenderingSettings= **/ null); + /** adsRenderingSettings= */ null); const adRequest = new google.ima.AdsRequest(); adRequest.adTagUrl = asset.adTagUri; adManager.requestClientSideAds(adRequest); diff --git a/docs/design/architecture.md b/docs/design/current/architecture.md similarity index 100% rename from docs/design/architecture.md rename to docs/design/current/architecture.md diff --git a/docs/design/cast.gv b/docs/design/current/cast.gv similarity index 100% rename from docs/design/cast.gv rename to docs/design/current/cast.gv diff --git a/docs/design/cast.gv.png b/docs/design/current/cast.gv.png similarity index 100% rename from docs/design/cast.gv.png rename to docs/design/current/cast.gv.png diff --git a/docs/design/chromecast.md b/docs/design/current/chromecast.md similarity index 100% rename from docs/design/chromecast.md rename to docs/design/current/chromecast.md diff --git a/docs/design/codec_preferences.md b/docs/design/current/codec_preferences.md similarity index 100% rename from docs/design/codec_preferences.md rename to docs/design/current/codec_preferences.md diff --git a/docs/design/dash-audio-channels.md b/docs/design/current/dash-audio-channels.md similarity index 100% rename from docs/design/dash-audio-channels.md rename to docs/design/current/dash-audio-channels.md diff --git a/docs/design/dash-manifests.md b/docs/design/current/dash-manifests.md similarity index 100% rename from docs/design/dash-manifests.md rename to docs/design/current/dash-manifests.md diff --git a/docs/design/dash-timeline.svg b/docs/design/current/dash-timeline.svg similarity index 100% rename from docs/design/dash-timeline.svg rename to docs/design/current/dash-timeline.svg diff --git a/docs/design/dataflow.gv b/docs/design/current/dataflow.gv similarity index 100% rename from docs/design/dataflow.gv rename to docs/design/current/dataflow.gv diff --git a/docs/design/dataflow.gv.png b/docs/design/current/dataflow.gv.png similarity index 100% rename from docs/design/dataflow.gv.png rename to docs/design/current/dataflow.gv.png diff --git a/docs/design/export.md b/docs/design/current/export.md similarity index 100% rename from docs/design/export.md rename to docs/design/current/export.md diff --git a/docs/design/fuzzy-locale-matching.md b/docs/design/current/fuzzy-locale-matching.md similarity index 100% rename from docs/design/fuzzy-locale-matching.md rename to docs/design/current/fuzzy-locale-matching.md diff --git a/docs/design/gap-jumping.md b/docs/design/current/gap-jumping.md similarity index 100% rename from docs/design/gap-jumping.md rename to docs/design/current/gap-jumping.md diff --git a/docs/design/lcevc-architecture.png b/docs/design/current/lcevc-architecture.png similarity index 100% rename from docs/design/lcevc-architecture.png rename to docs/design/current/lcevc-architecture.png diff --git a/docs/design/lcevc-demo.png b/docs/design/current/lcevc-demo.png similarity index 100% rename from docs/design/lcevc-demo.png rename to docs/design/current/lcevc-demo.png diff --git a/docs/design/lcevc-integration.md b/docs/design/current/lcevc-integration.md similarity index 100% rename from docs/design/lcevc-integration.md rename to docs/design/current/lcevc-integration.md diff --git a/docs/design/locale_compatibility.svg b/docs/design/current/locale_compatibility.svg similarity index 100% rename from docs/design/locale_compatibility.svg rename to docs/design/current/locale_compatibility.svg diff --git a/docs/design/locales_tree.svg b/docs/design/current/locales_tree.svg similarity index 100% rename from docs/design/locales_tree.svg rename to docs/design/current/locales_tree.svg diff --git a/docs/design/localization-design-principles.md b/docs/design/current/localization-design-principles.md similarity index 100% rename from docs/design/localization-design-principles.md rename to docs/design/current/localization-design-principles.md diff --git a/docs/design/newdemo.gv b/docs/design/current/newdemo.gv similarity index 100% rename from docs/design/newdemo.gv rename to docs/design/current/newdemo.gv diff --git a/docs/design/newdemo.gv.png b/docs/design/current/newdemo.gv.png similarity index 100% rename from docs/design/newdemo.gv.png rename to docs/design/current/newdemo.gv.png diff --git a/docs/design/offline.gv b/docs/design/current/offline.gv similarity index 100% rename from docs/design/offline.gv rename to docs/design/current/offline.gv diff --git a/docs/design/offline.gv.png b/docs/design/current/offline.gv.png similarity index 100% rename from docs/design/offline.gv.png rename to docs/design/current/offline.gv.png diff --git a/docs/design/offline.md b/docs/design/current/offline.md similarity index 100% rename from docs/design/offline.md rename to docs/design/current/offline.md diff --git a/docs/design/ownership.gv b/docs/design/current/ownership.gv similarity index 100% rename from docs/design/ownership.gv rename to docs/design/current/ownership.gv diff --git a/docs/design/ownership.gv.png b/docs/design/current/ownership.gv.png similarity index 100% rename from docs/design/ownership.gv.png rename to docs/design/current/ownership.gv.png diff --git a/docs/design/talking-about-languages.md b/docs/design/current/talking-about-languages.md similarity index 100% rename from docs/design/talking-about-languages.md rename to docs/design/current/talking-about-languages.md diff --git a/docs/design/timeline.svg b/docs/design/current/timeline.svg similarity index 100% rename from docs/design/timeline.svg rename to docs/design/current/timeline.svg diff --git a/docs/design/ui.md b/docs/design/current/ui.md similarity index 100% rename from docs/design/ui.md rename to docs/design/current/ui.md diff --git a/docs/design/ui_player_relationships.svg b/docs/design/current/ui_player_relationships.svg similarity index 100% rename from docs/design/ui_player_relationships.svg rename to docs/design/current/ui_player_relationships.svg diff --git a/docs/design/bg-fetch-after.gv b/docs/design/future_work/bg-fetch-after.gv similarity index 100% rename from docs/design/bg-fetch-after.gv rename to docs/design/future_work/bg-fetch-after.gv diff --git a/docs/design/bg-fetch-after.gv.png b/docs/design/future_work/bg-fetch-after.gv.png similarity index 100% rename from docs/design/bg-fetch-after.gv.png rename to docs/design/future_work/bg-fetch-after.gv.png diff --git a/docs/design/bg-fetch-before.gv b/docs/design/future_work/bg-fetch-before.gv similarity index 100% rename from docs/design/bg-fetch-before.gv rename to docs/design/future_work/bg-fetch-before.gv diff --git a/docs/design/bg-fetch-before.gv.png b/docs/design/future_work/bg-fetch-before.gv.png similarity index 100% rename from docs/design/bg-fetch-before.gv.png rename to docs/design/future_work/bg-fetch-before.gv.png diff --git a/docs/design/bg-fetch.md b/docs/design/future_work/bg-fetch.md similarity index 100% rename from docs/design/bg-fetch.md rename to docs/design/future_work/bg-fetch.md diff --git a/docs/design/REDESIGN.md b/docs/design/outdated/REDESIGN.md similarity index 99% rename from docs/design/REDESIGN.md rename to docs/design/outdated/REDESIGN.md index f2d1276496..c78b0aee49 100644 --- a/docs/design/REDESIGN.md +++ b/docs/design/outdated/REDESIGN.md @@ -206,7 +206,7 @@ separate browser support test in Shaka 1. ## Architecture Diagrams -See [architecture.md](architecture.md). +See [architecture.md](../current/architecture.md). ## Rough Sample APIs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..1315710e97 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,342 @@ +/*! @license + * Shaka Player + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +// ESlint config + +import js from '@eslint/js'; +import google from 'eslint-config-google'; +import jsdoc from 'eslint-plugin-jsdoc'; +import shakaRules from 'eslint-plugin-shaka-rules'; +import globals from 'globals'; + +// This is a matcher (usable in no-restricted-syntax) that matches either a +// test or a before/after block. +const testNameRegex = + '/^([fx]?it|(drm|quarantined)It|(before|after)(Each|All))$/'; +const testCall = `CallExpression[callee.name=${testNameRegex}]`; + +const commonNoRestrictedSyntax = [ + { + 'selector': + 'MemberExpression[object.name="goog"][property.name="inherits"]', + 'message': 'Don\'t use goog.inherits.', + }, + { + 'selector': ':not(MethodDefinition) > FunctionExpression', + 'message': 'Use arrow functions instead of "function" functions.', + }, + { + 'selector': 'CallExpression[callee.property.name="forEach"] >' + + ':function[params.length=1]', + 'message': 'Use for-of instead of forEach', + }, + { + // NOTE: prefer-spread rule covers .apply() already. + 'selector': 'CallExpression[callee.property.name=/^(bind|call)$/]', + 'message': 'Don\'t use Function bind/call.', + }, + { + 'selector': 'MemberExpression[property.name="prototype"]', + 'message': 'Use ES6 classes not .prototype.', + }, + { + 'selector': 'BinaryExpression[operator=/^([<>!=]=?)$/] > ' + + 'CallExpression[callee.property.name=indexOf]', + 'message': 'Use Array.includes instead of indexOf.', + }, +]; + +export default [ + { + ignores: ['!**/eslint.config.mjs'], + }, + js.configs.recommended, + jsdoc.configs['flat/recommended-error'], + google, + shakaRules.configs.config, + { + languageOptions: { + globals: globals.browser, + ecmaVersion: 2017, + }, + settings: { + jsdoc: { + mode: 'closure', + preferredTypes: { + object: 'Object', + symbol: 'Symbol', + }, + tagNamePreference: { + augments: 'extends', + constant: 'const', + constructor: 'constructor', + file: 'fileoverview', + returns: 'return', + }, + }, + }, + rules: { + // Things the compiler already takes care of, with more precision: {{{ + 'no-console': 'off', + 'no-eq-null': 'off', + 'no-eval': 'off', + 'no-undef': 'off', + // }}} + + // Things we should probably fix, but in stages in multiple commits: {{{ + + // These could catch real bugs + 'default-case': 'off', + // TODO: Enable no-loop-func in next eslint release. We can't use it + // now since it doesn't allow capturing "const" variables, which is safe + 'no-loop-func': 'off', + // Conflicts with some Closure declarations + 'no-unused-expressions': 'off', + 'prefer-promise-reject-errors': 'off', + // These could improve readability + 'complexity': 'off', + 'no-negated-condition': 'off', + 'no-shadow': 'off', + // }}} + + // "Possible error" rules: {{{ + 'no-async-promise-executor': 'error', + 'no-await-in-loop': 'error', + 'no-empty': ['error', { + allowEmptyCatch: true, + }], + 'no-misleading-character-class': 'error', + 'no-template-curly-in-string': 'error', + 'no-fallthrough': ['error', { + allowEmptyCase: true, + }], + // TODO: Try to re-enable this if possible. Right now, it produces way + // too many false-positives with eslint 7. + // It worked well enough in eslint 5. + // 'require-atomic-updates': 'error', + // }}} + + // "Best practices" rules: {{{ + 'accessor-pairs': 'error', + 'array-callback-return': 'error', + // causes issues when implementing an interface + 'class-methods-use-this': 'off', + 'consistent-return': 'error', + 'dot-location': ['error', 'property'], + 'dot-notation': 'off', // We use bracket notation in tests on purpose + 'eqeqeq': 'off', // Compiler handles type checking in advance + 'guard-for-in': 'off', + 'no-alert': 'error', + 'no-caller': 'error', + 'no-div-regex': 'error', + 'no-extend-native': 'error', // May conflict with future polyfills + 'no-extra-label': 'error', + 'no-floating-decimal': 'error', + 'no-implicit-coercion': ['error', { + allow: ['!!'], + }], + 'no-implied-eval': 'error', + 'no-invalid-this': 'error', + 'no-iterator': 'error', + 'no-labels': 'error', + 'no-lone-blocks': 'error', + 'no-multi-spaces': ['error', { + ignoreEOLComments: true, + }], + 'no-multi-str': 'error', + 'no-new': 'error', + 'no-new-func': 'error', + 'no-new-wrappers': 'error', + 'no-octal-escape': 'error', + 'no-proto': 'error', + 'no-return-assign': 'error', + 'no-return-await': 'error', + 'no-script-url': 'error', + 'no-self-compare': 'error', + 'no-sequences': 'error', + 'no-throw-literal': 'error', + 'no-unmodified-loop-condition': 'error', + // Interface implementations may not require all args + 'no-unused-vars': 'off', + 'no-useless-call': 'error', + 'no-useless-catch': 'error', + 'no-useless-concat': 'error', + 'no-useless-return': 'error', + 'no-void': 'error', + 'no-warning-comments': 'off', // TODO and FIXME are fine + 'radix': ['error', 'always'], + 'require-await': 'error', + 'wrap-iife': ['error', 'inside'], + 'yoda': ['error', 'never'], + // }}} + + // "Variables" rules: {{{ + 'no-label-var': 'error', + 'no-shadow-restricted-names': 'error', + 'no-undef-init': 'off', // Sometimes necessary with hacky compiler casts + 'no-undefined': 'off', // We use undefined in many places, legitimately + // Does not know when things are executed, false positives + 'no-use-before-define': 'off', + // }}} + + // "Stylistic Issues" rules: {{{ + 'array-bracket-newline': ['error', 'consistent'], + 'block-spacing': ['error', 'always'], + 'brace-style': ['error', '1tbs', { + allowSingleLine: true, + }], + 'id-denylist': ['error', 'async'], + 'lines-between-class-members': 'error', + 'max-statements-per-line': ['error', { + max: 1, + }], + 'new-parens': 'error', + 'no-mixed-operators': ['error', { + groups: [['&', '|', '^', '~', '<<', '>>', '>>>', '&&', '||']], + allowSamePrecedence: false, + }], + 'no-restricted-syntax': [ + 'error', + ...commonNoRestrictedSyntax, + ], + 'no-whitespace-before-property': 'error', + // cspell:ignore nonblock + 'nonblock-statement-body-position': ['error', 'below'], + 'operator-assignment': 'error', + 'spaced-comment': ['error', 'always', { + // Characters which may be glued to the start of a comment block, but + // which do not violate the rule. The "*" is for jsdoc's "/**" syntax, + // and the "!" is for the "/*!" of license headers which are passed + // verbatim through the compiler. + markers: ['*', '!'], + }], + // }}} + + // "ECMAScript 6" rules: {{{ + 'arrow-spacing': 'error', + 'no-useless-constructor': 'error', + 'prefer-arrow-callback': 'error', + 'prefer-const': ['error', { + ignoreReadBeforeAssign: true, + }], + // }}} + + // jsdoc rules {{{ + 'jsdoc/check-tag-names': ['error', { + definedTags: ['exportDoc', 'exportInterface'], + }], + // Do not check license, authors, etc + 'jsdoc/check-values': 'off', + // This should be checked by the compiler + 'jsdoc/no-undefined-types': 'off', + // Some params/props/returns are self-explanatory + 'jsdoc/require-param-description': 'off', + 'jsdoc/require-property-description': 'off', + 'jsdoc/require-returns-description': 'off', + 'jsdoc/tag-lines': 'off', + // It throws syntax error on @suppress {missingReturn} + 'jsdoc/valid-types': 'off', + // }}} + }, + }, + { + files: ['test/**/*.js'], + rules: { + 'no-restricted-syntax': [ + 'error', + { + 'selector': 'CallExpression[callee.name="beforeAll"] ' + + ':matches(' + + 'CallExpression[callee.property.name="createSpy"],' + + 'CallExpression[callee.name="spyOn"])', + 'message': 'Create spies in beforeEach, not beforeAll.', + }, + { + 'selector': testCall + ' > :function[params.length>0]', + 'message': 'Use async instead of "done" in tests.', + }, + { + 'selector': testCall + ' > CallExpression', + 'message': 'Use filterDescribe instead of checkAndRun calls', + }, + { + 'selector': 'CatchClause', + 'message': 'Use expect.toThrow or expectAsync.toBeRejected', + }, + { + 'selector': 'CallExpression[callee.name=expect] >' + + 'CallExpression[callee.property.name=count]' + + '[callee.object.property.name=calls]', + 'message': 'Use expect.toHaveBeenCalledTimes', + }, + { + 'selector': + 'CallExpression[callee.property.name=toHaveBeenCalledTimes] >' + + 'Literal[value=0]', + 'message': 'Use expect.not.toHaveBeenCalled', + }, + ...commonNoRestrictedSyntax, + ], + }, + }, + { + files: [ + // Closure requires using var in externs. + 'ui/externs/*.js', + 'externs/**/*.js', + 'test/test/externs/*.js', + // Use var in load.js so it works in old browsers. We'll use + // compiled mode for the main library and the demo. + 'demo/load.js', + ], + rules: { + 'no-restricted-syntax': 'off', + 'no-var': 'off', + 'jsdoc/require-returns-check': 'off', + }, + }, + { + files: [ + // Test code should still use "arguments", since the alternate + // "rest parameter" syntax won't work in uncompiled code on IE. + 'test/**/*.js', + // These two files use "arguments" to patch over functions. It + // is difficult to reason about whether or not these instances + // would always work with rest parameters, so just allow them to + 'demo/log_section.js', + 'lib/debug/asserts.js', + ], + rules: { + 'prefer-rest-params': 'off', + }, + }, + { + files: ['externs/**/*.js'], + rules: { + // Disable rules on useless constructors so we can use ES6 classes in + // externs. + 'no-useless-constructor': 'off', + }, + }, + { + files: ['ui/externs/*.js', 'externs/**/*.js', 'test/test/externs/*.js'], + rules: { + // Externs naturally redeclare things eslint knows about. + 'no-redeclare': 'off', + }, + }, + { + files: [ + 'demo/load.js', + 'externs/**/*.js', + 'test/**/*.js', + ], + rules: { + // JSDoc is not strictly required in externs, tests, and in load.js. + 'jsdoc/require-jsdoc': 'off', + }, + }, +]; diff --git a/externs/airplay.js b/externs/airplay.js index f549e67ba1..b930623fd0 100644 --- a/externs/airplay.js +++ b/externs/airplay.js @@ -26,5 +26,5 @@ HTMLMediaElement.prototype.webkitShowPlaybackTargetPicker = function() {}; var AirPlayEvent = class extends Event {}; -/** @type {String} */ +/** @type {string} */ AirPlayEvent.prototype.availability; diff --git a/externs/isoboxer.js b/externs/isoboxer.js index 07e2bbf7fa..02a54c127a 100644 --- a/externs/isoboxer.js +++ b/externs/isoboxer.js @@ -148,8 +148,8 @@ var ISOBoxerUtils; * @property {function(!string, !number, !string, !number)} _procFieldArray * @property {function(!string, !number, !function(!ISOEntry))} _procEntries * @property {function(!ISOBox, !string, !string, !number)} _procEntryField - * @property {function(!ISOBox, !string, !number, !function(!ISOEntry))} - * _procSubEntries + * @property {function(!ISOBox, !string, !number, !function(!ISOEntry)) + * } _procSubEntries * @property {string} major_brand * @property {number} minor_version * @property {Array.} compatible_brands diff --git a/externs/lcevc.js b/externs/lcevc.js index d5cdcf20da..6a2c103e0e 100644 --- a/externs/lcevc.js +++ b/externs/lcevc.js @@ -5,11 +5,11 @@ */ /** -* @fileoverview Externs for LcevcDec -* compiler. -* -* @externs -*/ + * @fileoverview Externs for LcevcDec + * compiler. + * + * @externs + */ // This empty namespace is declared to check if LcevcDec libraries are loaded. /** @const */ @@ -18,9 +18,9 @@ var libDPIModule = {}; var LCEVCdec = {}; /** -* LCEVC Dec constructor -* @constructor -*/ + * LCEVC Dec constructor + * @constructor + */ LCEVCdec.LCEVCdec = class { /** * @param {HTMLVideoElement} media diff --git a/externs/mediasession.js b/externs/mediasession.js index facd8c4857..8a14c1eece 100644 --- a/externs/mediasession.js +++ b/externs/mediasession.js @@ -37,8 +37,9 @@ const MediaSession = class { /** @type {string} */ this.type = type; - /** @type {!function(!{action: string, seekOffset: ?number, - * seekTime: ?number})} + /** + * @type {!function(!{action: string, seekOffset: ?number, + * seekTime: ?number})} */ this.callback = callback; } diff --git a/externs/prefixed_eme.js b/externs/prefixed_eme.js index 4f09a33641..1dd761d83b 100644 --- a/externs/prefixed_eme.js +++ b/externs/prefixed_eme.js @@ -49,7 +49,7 @@ HTMLMediaElement.prototype.generateKeyRequest = * @param {string} mimeType * @param {string=} keySystem * @return {string} '', 'maybe', or 'probably' - * @override the standard one-argument version + * @override */ HTMLVideoElement.prototype.canPlayType = function(mimeType, keySystem) {}; diff --git a/externs/shaka/manifest.js b/externs/shaka/manifest.js index cac0a24bae..ceda738dae 100644 --- a/externs/shaka/manifest.js +++ b/externs/shaka/manifest.js @@ -118,29 +118,29 @@ shaka.extern.Manifest; /** * @typedef {{ -* id: string, -* audioStreams: !Array., -* videoStreams: !Array., -* textStreams: !Array., -* imageStreams: !Array. -* }} -* -* @description Contains the streams from one DASH period. -* For use in {@link shaka.util.PeriodCombiner}. -* -* @property {string} id -* The Period ID. -* @property {!Array.} audioStreams -* The audio streams from one Period. -* @property {!Array.} videoStreams -* The video streams from one Period. -* @property {!Array.} textStreams -* The text streams from one Period. -* @property {!Array.} imageStreams -* The image streams from one Period. -* -* @exportDoc -*/ + * id: string, + * audioStreams: !Array., + * videoStreams: !Array., + * textStreams: !Array., + * imageStreams: !Array. + * }} + * + * @description Contains the streams from one DASH period. + * For use in {@link shaka.util.PeriodCombiner}. + * + * @property {string} id + * The Period ID. + * @property {!Array.} audioStreams + * The audio streams from one Period. + * @property {!Array.} videoStreams + * The video streams from one Period. + * @property {!Array.} textStreams + * The text streams from one Period. + * @property {!Array.} imageStreams + * The image streams from one Period. + * + * @exportDoc + */ shaka.extern.Period; /** @@ -489,8 +489,8 @@ shaka.extern.SegmentIndex = class { * @property {!Array.} roles * The roles of the stream as they appear on the manifest, * e.g. 'main', 'caption', or 'commentary'. - * @property {?shaka.media.ManifestParser.AccessibilityPurpose} - * accessibilityPurpose + * @property {?shaka.media.ManifestParser.AccessibilityPurpose + * } accessibilityPurpose * The DASH accessibility descriptor, if one was provided for this stream. * @property {boolean} forced * Defaults to false.
diff --git a/externs/shaka/net.js b/externs/shaka/net.js index 9fed70bd5d..04c289e678 100644 --- a/externs/shaka/net.js +++ b/externs/shaka/net.js @@ -191,18 +191,18 @@ shaka.extern.SchemePlugin; /** * @typedef {{ -* minBytesForProgressEvents: (number|undefined) -* }} -* -* @description -* Defines configuration object to use by SchemePlugins. -* -* @property {(number|undefined)} minBytesForProgressEvents -* Defines minimum number of bytes that should be use to emit progress event, -* if possible. -* -* @exportDoc -*/ + * minBytesForProgressEvents: (number|undefined) + * }} + * + * @description + * Defines configuration object to use by SchemePlugins. + * + * @property {(number|undefined)} minBytesForProgressEvents + * Defines minimum number of bytes that should be use to emit progress event, + * if possible. + * + * @exportDoc + */ shaka.extern.SchemePluginConfig; diff --git a/externs/shaka/player.js b/externs/shaka/player.js index 8ed0b49c82..c77e0c0c28 100644 --- a/externs/shaka/player.js +++ b/externs/shaka/player.js @@ -350,8 +350,8 @@ shaka.extern.BufferedInfo; * The roles of the audio in the track, e.g. 'main' or * 'commentary'. Will be null for text tracks or variant tracks * without audio. - * @property {?shaka.media.ManifestParser.AccessibilityPurpose} - * accessibilityPurpose + * @property {?shaka.media.ManifestParser.AccessibilityPurpose + * } accessibilityPurpose * The DASH accessibility descriptor, if one was provided for this track. * For text tracks, this describes the text; otherwise, this is for the audio. * @property {boolean} forced @@ -1545,8 +1545,8 @@ shaka.extern.DynamicTargetLatencyConfiguration; * Number of seconds that playback stays in panic mode after a rebuffering. *
* Defaults to 60. - * @property {shaka.extern.DynamicTargetLatencyConfiguration} - * dynamicTargetLatency + * @property {shaka.extern.DynamicTargetLatencyConfiguration + * } dynamicTargetLatency * * The dynamic target latency config for dynamically adjusting the target * latency to be closer to edge when network conditions are good and to back @@ -1826,10 +1826,12 @@ shaka.extern.LiveSyncConfiguration; *
* Defaults to 0.5. * @property {boolean} infiniteLiveStreamDuration - * If true, the media source live duration - * set as aInfinity + * If true, the media source duration of livestreams will be set + * to Infinity. Otherwise, it will be set to a high but + * non-infinite number (2^32). *
- * Defaults to false. + * Defaults to false except on Safari 17 or above whose default + * value is true. * @property {number} preloadNextUrlWindow * The window of time at the end of the presentation to begin preloading the * next URL, such as one specified by a urn:mpeg:dash:chaining:2016 element @@ -2263,8 +2265,8 @@ shaka.extern.LcevcConfiguration; * numberOfParallelDownloads: number * }} * - * @property {function(shaka.extern.TrackList):!Promise} - * trackSelectionCallback + * @property {function(shaka.extern.TrackList): + * !Promise} trackSelectionCallback * Called inside store() to determine which tracks to save from a * manifest. It is passed an array of Tracks from the manifest and it should * return an array of the tracks to store. @@ -2369,8 +2371,8 @@ shaka.extern.TextDisplayerConfiguration; * Media source configuration and settings. * @property {shaka.extern.AbrManager.Factory} abrFactory * A factory to construct an abr manager. - * @property {shaka.media.AdaptationSetCriteria.Factory} - * adaptationSetCriteriaFactory + * @property {shaka.media.AdaptationSetCriteria.Factory + * } adaptationSetCriteriaFactory * A factory to construct an adaptation set criteria. * @property {shaka.extern.AbrConfiguration} abr * ABR configuration and settings. diff --git a/karma.conf.js b/karma.conf.js index d0565e180c..b0e1b18e01 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -12,7 +12,6 @@ const _ = require('lodash'); const fs = require('fs'); const glob = require('glob'); const Jimp = require('jimp'); -const path = require('path'); const rimraf = require('rimraf'); const {ssim} = require('ssim.js'); const util = require('karma/common/util'); @@ -940,7 +939,7 @@ WebDriverScreenshotMiddlewareFactory.$inject = ['launcher']; * This could have been done through a fork of Karma itself, but this plugin * was clearer in some ways than using a fork of a now-extinct project. * - * @param {karma.Launcher} launcher + * @param {!Array} reporters * @param {string} settingsJson * @return {karma.Middleware} */ diff --git a/lib/ads/ad_manager.js b/lib/ads/ad_manager.js index 460957ac09..8c978a8cc4 100644 --- a/lib/ads/ad_manager.js +++ b/lib/ads/ad_manager.js @@ -538,9 +538,9 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget { /** - * @override - * @export - */ + * @override + * @export + */ onAssetUnload() { if (this.interstitialAdManager_) { this.interstitialAdManager_.stop(); diff --git a/lib/ads/media_tailor_ad.js b/lib/ads/media_tailor_ad.js index efe76ee67f..fb8fadb82e 100755 --- a/lib/ads/media_tailor_ad.js +++ b/lib/ads/media_tailor_ad.js @@ -18,6 +18,7 @@ shaka.ads.MediaTailorAd = class { * @param {mediaTailor.Ad} mediaTailorAd * @param {number} adPosition * @param {number} totalAds + * @param {boolean} isLinear * @param {HTMLMediaElement} video */ constructor(mediaTailorAd, adPosition, totalAds, isLinear, video) { diff --git a/lib/ads/media_tailor_ad_manager.js b/lib/ads/media_tailor_ad_manager.js index e8640d434c..611d19f643 100755 --- a/lib/ads/media_tailor_ad_manager.js +++ b/lib/ads/media_tailor_ad_manager.js @@ -80,7 +80,8 @@ shaka.ads.MediaTailorAdManager = class { /** @private {!Map.>} */ this.staticResources_ = new Map(); - /** @private {!Array.<{target: EventTarget, type: string, + /** + * @private {!Array.<{target: EventTarget, type: string, * listener: shaka.util.EventManager.ListenerType}>} */ this.adListeners_ = []; diff --git a/lib/ads/server_side_ad_manager.js b/lib/ads/server_side_ad_manager.js index 55e5a06df4..a36880e625 100644 --- a/lib/ads/server_side_ad_manager.js +++ b/lib/ads/server_side_ad_manager.js @@ -39,8 +39,9 @@ shaka.ads.ServerSideAdManager = class { /** @private {?shaka.extern.AdsConfiguration} */ this.config_ = null; - /** @private - {?shaka.util.PublicPromise.} */ + /** + * @private {?shaka.util.PublicPromise.} + */ this.streamPromise_ = null; /** @private {number} */ diff --git a/lib/cast/cast_receiver.js b/lib/cast/cast_receiver.js index ba33075da7..d53db2b4c9 100644 --- a/lib/cast/cast_receiver.js +++ b/lib/cast/cast_receiver.js @@ -62,8 +62,10 @@ shaka.cast.CastReceiver = class extends shaka.util.FakeEventTarget { /** @private {?function(string):string} */ this.contentIdCallback_ = contentIdCallback || - /** @param {string} contentId - @return {string} */ + /** + * @param {string} contentId + * @return {string} + */ ((contentId) => contentId); /** diff --git a/lib/cea/cea608_data_channel.js b/lib/cea/cea608_data_channel.js index d6f04d063c..fe4cb29e81 100644 --- a/lib/cea/cea608_data_channel.js +++ b/lib/cea/cea608_data_channel.js @@ -794,21 +794,21 @@ shaka.cea.Cea608DataChannel.Style; /** * CEA closed captions packet. * @typedef {{ - * pts: number, - * type: number, - * ccData1: number, - * ccData2: number, - * order: number - * }} - * - * @property {number} pts - * Presentation timestamp (in second) at which this packet was received. - * @property {number} type - * Type of the packet. Either 0 or 1, representing the CEA-608 field. - * @property {number} ccData1 CEA-608 byte 1. - * @property {number} ccData2 CEA-608 byte 2. - * @property {number} order - * A number indicating the order this packet was received in a sequence - * of packets. Used to break ties in a stable sorting algorithm - */ + * pts: number, + * type: number, + * ccData1: number, + * ccData2: number, + * order: number + * }} + * + * @property {number} pts + * Presentation timestamp (in second) at which this packet was received. + * @property {number} type + * Type of the packet. Either 0 or 1, representing the CEA-608 field. + * @property {number} ccData1 CEA-608 byte 1. + * @property {number} ccData2 CEA-608 byte 2. + * @property {number} order + * A number indicating the order this packet was received in a sequence + * of packets. Used to break ties in a stable sorting algorithm + */ shaka.cea.Cea608DataChannel.Cea608Packet; diff --git a/lib/cea/cea708_window.js b/lib/cea/cea708_window.js index 81d04a7a47..25331402e0 100644 --- a/lib/cea/cea708_window.js +++ b/lib/cea/cea708_window.js @@ -18,6 +18,7 @@ goog.require('shaka.text.CueRegion'); shaka.cea.Cea708Window = class { /** * @param {number} windowNum + * @param {number} parentService */ constructor(windowNum, parentService) { /** @@ -229,6 +230,7 @@ shaka.cea.Cea708Window = class { } /** + * @return {boolean} * @private */ isPenInBounds_() { diff --git a/lib/dash/content_protection.js b/lib/dash/content_protection.js index 64ec40ea63..273faa2dc9 100644 --- a/lib/dash/content_protection.js +++ b/lib/dash/content_protection.js @@ -293,25 +293,43 @@ shaka.dash.ContentProtection = class { * @return {string} */ static getPlayReadyLicenseUrl(element) { - const dashIfLaurlNode = shaka.util.TXml.findChildNS( + const TXml = shaka.util.TXml; + const dashIfLaurlNode = TXml.findChildNS( element.node, shaka.dash.ContentProtection.DashIfNamespaceUri_, 'Laurl', ); if (dashIfLaurlNode) { - const textContents = shaka.util.TXml.getTextContents(dashIfLaurlNode); + const textContents = TXml.getTextContents(dashIfLaurlNode); if (textContents) { return textContents; } } - const proNode = shaka.util.TXml.findChildNS( + const proNode = TXml.findChildNS( element.node, 'urn:microsoft:playready', 'pro'); + if (proNode) { + const textContents = TXml.getTextContents(proNode); + if (textContents) { + return shaka.drm.PlayReady.getLicenseUrl(proNode); + } + } - if (!proNode || !shaka.util.TXml.getTextContents(proNode)) { - return ''; + const psshNode = TXml.findChildNS( + element.node, shaka.dash.ContentProtection.CencNamespaceUri_, 'pssh'); + if (psshNode) { + const textContents = TXml.getTextContents(psshNode); + if (textContents) { + const proData = shaka.util.Pssh.getPsshData( + shaka.util.Uint8ArrayUtils.fromBase64(textContents)); + const proString = shaka.util.Uint8ArrayUtils.toStandardBase64(proData); + const reBuildProNode = + TXml.parseXmlString('' + proString + ''); + goog.asserts.assert(reBuildProNode, 'Must have pro node'); + return shaka.drm.PlayReady.getLicenseUrl(reBuildProNode); + } } - return shaka.drm.PlayReady.getLicenseUrl(proNode); + return ''; } /** @@ -331,7 +349,7 @@ shaka.dash.ContentProtection = class { const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils; const textContent = - /** @type{string} */ (shaka.util.TXml.getTextContents(proNode)); + /** @type {string} */ (shaka.util.TXml.getTextContents(proNode)); const data = Uint8ArrayUtils.fromBase64(textContent); const systemId = new Uint8Array([ 0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40, 0x42, 0x86, diff --git a/lib/dash/dash_parser.js b/lib/dash/dash_parser.js index a3269c6fb8..98e7bb1ab7 100644 --- a/lib/dash/dash_parser.js +++ b/lib/dash/dash_parser.js @@ -1646,8 +1646,8 @@ shaka.dash.DashParser = class { * @param {boolean} disabled * @param {!Array.} adaptationSets * @param {string} contentType - @private - */ + * @private + */ getStreamsFromSets_(disabled, adaptationSets, contentType) { if (disabled || !adaptationSets.length) { return []; @@ -2107,8 +2107,8 @@ shaka.dash.DashParser = class { * @param {!Array.} roles * @param {Map.} closedCaptions * @param {!shaka.extern.xml.Node} node - * @param {?shaka.media.ManifestParser.AccessibilityPurpose} - * accessibilityPurpose + * @param {?shaka.media.ManifestParser.AccessibilityPurpose + * } accessibilityPurpose * @param {?number} lastSegmentNumber * * @return {?shaka.extern.Stream} The Stream, or null when there is a @@ -3426,8 +3426,8 @@ shaka.dash.DashParser.GenerateSegmentIndexFunction; * Contains information about a Stream. This is passed from the createStreamInfo * methods. * - * @property {shaka.dash.DashParser.GenerateSegmentIndexFunction} - * generateSegmentIndex + * @property {shaka.dash.DashParser.GenerateSegmentIndexFunction + * } generateSegmentIndex * An async function to create the SegmentIndex for the stream. */ shaka.dash.DashParser.StreamInfo; diff --git a/lib/dash/mpd_utils.js b/lib/dash/mpd_utils.js index 411c83de2d..adda89f2b8 100644 --- a/lib/dash/mpd_utils.js +++ b/lib/dash/mpd_utils.js @@ -324,7 +324,7 @@ shaka.dash.MpdUtils = class { * @param {function(?shaka.dash.DashParser.InheritanceFrame): * ?shaka.extern.xml.Node} callback * @return {!Array.} - */ + */ static getNodes(context, callback) { const Functional = shaka.util.Functional; goog.asserts.assert( @@ -505,7 +505,7 @@ shaka.dash.MpdUtils = class { * @param {boolean} failGracefully * @param {string} baseUri * @param {!shaka.net.NetworkingEngine} networkingEngine - * @param {number=} linkDepth, default set to 0 + * @param {number=} linkDepth default set to 0 * @return {!shaka.util.AbortableOperation.} */ static processXlinks( diff --git a/lib/dash/segment_template.js b/lib/dash/segment_template.js index 146db855f7..fd44b853df 100644 --- a/lib/dash/segment_template.js +++ b/lib/dash/segment_template.js @@ -747,7 +747,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex { * @param {boolean} shouldFit * @param {shaka.extern.aesKey|undefined} aesKey * @param {number} segmentSequenceCadence - */ + */ constructor(templateInfo, representationId, bandwidth, getBaseUris, urlParams, periodStart, periodEnd, initSegmentReference, shouldFit, aesKey, segmentSequenceCadence) { diff --git a/lib/dependencies/all.js b/lib/dependencies/all.js index 3df6dcdad5..79395283d3 100644 --- a/lib/dependencies/all.js +++ b/lib/dependencies/all.js @@ -60,6 +60,7 @@ shaka.dependencies.Allowed = { ISOBoxer: 'ISOBoxer', }; +// eslint-disable-next-line jsdoc/require-returns /** * Contains accessor functions to shared dependencies that could be used by * other components. The default accessors can be overridden. diff --git a/lib/drm/drm_engine.js b/lib/drm/drm_engine.js index e3471631ac..59031d21c6 100644 --- a/lib/drm/drm_engine.js +++ b/lib/drm/drm_engine.js @@ -1649,7 +1649,7 @@ shaka.drm.DrmEngine = class { goog.asserts.assert(challenge.attributes['encoding'] == 'base64encoded', 'Unexpected PlayReady challenge encoding!'); request.body = shaka.util.Uint8ArrayUtils.fromBase64( - /** @type{string} */(shaka.util.TXml.getTextContents(challenge))); + /** @type {string} */(shaka.util.TXml.getTextContents(challenge))); } /** @@ -2062,17 +2062,47 @@ shaka.drm.DrmEngine = class { support.set(keySystem, null); } + const checkKeySystem = (keySystem) => { + // Our Polyfill will reject anything apart com.apple.fps key systems. + // It seems the Safari modern EME API will allow to request a + // MediaKeySystemAccess for the ClearKey CDM, create and update a key + // session but playback will never start + // Safari bug: https://bugs.webkit.org/show_bug.cgi?id=231006 + if (shaka.drm.DrmUtils.isClearKeySystem(keySystem) && + shaka.util.Platform.isSafari()) { + return false; + } + // FairPlay is a proprietary DRM from Apple and will never work on + // Windows. + if (shaka.drm.DrmUtils.isFairPlayKeySystem(keySystem) && + shaka.util.Platform.isWindows()) { + return false; + } + // PlayReady is a proprietary DRM from Microsoft and will never work on + // Apple platforms + if (shaka.drm.DrmUtils.isPlayReadyKeySystem(keySystem) && + (shaka.util.Platform.isMac() || shaka.util.Platform.isApple())) { + return false; + } + // Mozilla has no intention of supporting PlayReady according to + // comments posted on Bugzilla. + if (shaka.drm.DrmUtils.isPlayReadyKeySystem(keySystem) && + shaka.util.Platform.isFirefox()) { + return false; + } + // We are sure that WisePlay is not supported on Windows or macOS. + if (shaka.drm.DrmUtils.isWisePlayKeySystem(keySystem) && + (shaka.util.Platform.isWindows() || shaka.util.Platform.isMac())) { + return false; + } + return true; + }; + // Test each key system and encryption scheme. const tests = []; for (const encryptionScheme of testEncryptionSchemes) { for (const keySystem of testKeySystems) { - // Our Polyfill will reject anything apart com.apple.fps key systems. - // It seems the Safari modern EME API will allow to request a - // MediaKeySystemAccess for the ClearKey CDM, create and update a key - // session but playback will never start - // Safari bug: https://bugs.webkit.org/show_bug.cgi?id=231006 - if (keySystem === 'org.w3.clearkey' && - shaka.util.Platform.isSafari()) { + if (!checkKeySystem(keySystem)) { continue; } tests.push(testSystemEme(keySystem, encryptionScheme, '', '')); @@ -2082,6 +2112,9 @@ shaka.drm.DrmEngine = class { for (const keySystem of testKeySystems) { for (const robustness of (testRobustness[keySystem] || [])) { + if (!checkKeySystem(keySystem)) { + continue; + } tests.push(testSystemEme(keySystem, null, robustness, '')); tests.push(testSystemEme(keySystem, null, '', robustness)); tests.push(testSystemMcap(keySystem, null, robustness, '')); @@ -2430,8 +2463,8 @@ shaka.drm.DrmEngine = class { * care to eliminate duplicates. * * @param {!Array.} drmInfos - * @param {!Array.} licenseServers * @param {!Array.} encryptionSchemes + * @param {!Array.} licenseServers * @param {!Array.} serverCerts * @param {!Array.} serverCertificateUris * @param {!Array.} initDatas @@ -2442,8 +2475,10 @@ shaka.drm.DrmEngine = class { static processDrmInfos_( drmInfos, encryptionSchemes, licenseServers, serverCerts, serverCertificateUris, initDatas, keyIds, keySystemUris) { - /** @type {function(shaka.extern.InitDataOverride, - * shaka.extern.InitDataOverride):boolean} */ + /** + * @type {function(shaka.extern.InitDataOverride, + * shaka.extern.InitDataOverride):boolean} + */ const initDataOverrideEqual = (a, b) => { if (a.keyId && a.keyId == b.keyId) { // Two initDatas with the same keyId are considered to be the same, @@ -2538,8 +2573,8 @@ shaka.drm.DrmEngine = class { * * @param {shaka.extern.DrmInfo} drmInfo * @param {!Map.} servers - * @param {!Map.} - * advancedConfigs + * @param {!Map.} advancedConfigs * @param {!Object.} keySystemsMapping * @private */ diff --git a/lib/drm/drm_utils.js b/lib/drm/drm_utils.js index df840c3606..1d0dca32fd 100644 --- a/lib/drm/drm_utils.js +++ b/lib/drm/drm_utils.js @@ -108,7 +108,8 @@ shaka.drm.DrmUtils = class { /** * @param {?shaka.extern.DrmInfo} drmInfo - * @return {string} */ + * @return {string} + */ static keySystem(drmInfo) { return drmInfo ? drmInfo.keySystem : ''; } @@ -157,6 +158,14 @@ shaka.drm.DrmUtils = class { return false; } + /** + * @param {?string} keySystem + * @return {boolean} + */ + static isWisePlayKeySystem(keySystem) { + return keySystem === 'com.huawei.wiseplay'; + } + /** * A method for generating a key for the MediaKeySystemAccessRequests cache. * @@ -213,7 +222,7 @@ shaka.drm.DrmUtils = class { const DrmUtils = shaka.drm.DrmUtils; const key = DrmUtils.generateKeySystemCacheKey_( videoCodec, audioCodec, keySystem); - return DrmUtils.memoizedMediaKeySystemAccessRequests_.set(key, mksa); + DrmUtils.memoizedMediaKeySystemAccessRequests_.set(key, mksa); } /** diff --git a/lib/drm/playready.js b/lib/drm/playready.js index 7793745a48..8439f72214 100644 --- a/lib/drm/playready.js +++ b/lib/drm/playready.js @@ -107,7 +107,8 @@ shaka.drm.PlayReady = class { if (elem.children) { for (const child of elem.children) { if (child.tagName == 'LA_URL') { - return /** @type{string} */(shaka.util.TXml.getTextContents(child)); + return /** @type {string} */( + shaka.util.TXml.getTextContents(child)); } } } @@ -128,7 +129,7 @@ shaka.drm.PlayReady = class { const PLAYREADY_RECORD_TYPES = shaka.drm.PlayReady.PLAYREADY_RECORD_TYPES; const bytes = shaka.util.Uint8ArrayUtils.fromBase64( - /** @type{string} */ (shaka.util.TXml.getTextContents(element))); + /** @type {string} */ (shaka.util.TXml.getTextContents(element))); const records = shaka.drm.PlayReady.parseMsPro_(bytes); const record = records.filter((record) => { return record.type === PLAYREADY_RECORD_TYPES.RIGHTS_MANAGEMENT; @@ -153,12 +154,17 @@ shaka.drm.PlayReady = class { * @return {string} */ static getLicenseUrl(element) { - const headerObject = shaka.drm.PlayReady.getPlayReadyHeaderObject_(element); - if (!headerObject) { + try { + const headerObject = + shaka.drm.PlayReady.getPlayReadyHeaderObject_(element); + if (!headerObject) { + return ''; + } + + return shaka.drm.PlayReady.getLaurl_(headerObject); + } catch (e) { return ''; } - - return shaka.drm.PlayReady.getLaurl_(headerObject); } /** @@ -183,7 +189,7 @@ shaka.drm.PlayReady = class { // GUID: [DWORD, WORD, WORD, 8-BYTE] const guidBytes = shaka.util.Uint8ArrayUtils.fromBase64( - /** @type{string} */ (shaka.util.TXml.getTextContents(kid))); + /** @type {string} */ (shaka.util.TXml.getTextContents(kid))); // Reverse byte order from little-endian to big-endian const kidBytes = new Uint8Array([ guidBytes[3], guidBytes[2], guidBytes[1], guidBytes[0], diff --git a/lib/hls/hls_parser.js b/lib/hls/hls_parser.js index 6836518115..9acf85c707 100644 --- a/lib/hls/hls_parser.js +++ b/lib/hls/hls_parser.js @@ -210,7 +210,8 @@ shaka.hls.HlsParser = class { /** @private {number} */ this.lastTargetDuration_ = Infinity; - /** Partial segments target duration. + /** + * Partial segments target duration. * @private {number} */ this.partialTargetDuration_ = 0; @@ -224,7 +225,8 @@ shaka.hls.HlsParser = class { /** @private {shaka.util.OperationManager} */ this.operationManager_ = new shaka.util.OperationManager(); - /** A map from closed captions' group id, to a map of closed captions info. + /** + * A map from closed captions' group id, to a map of closed captions info. * {group id -> {closed captions channel id -> language}} * @private {Map.>} */ @@ -233,11 +235,13 @@ shaka.hls.HlsParser = class { /** @private {Map.} */ this.groupIdToCodecsMap_ = new Map(); - /** A cache mapping EXT-X-MAP tag info to the InitSegmentReference created + /** + * A cache mapping EXT-X-MAP tag info to the InitSegmentReference created * from the tag. * The key is a string combining the EXT-X-MAP tag's absolute uri, and * its BYTERANGE if available. - * {!Map.} */ + * @private {!Map.} + */ this.mapTagToInitSegmentRefMap_ = new Map(); /** @private {Map.} */ @@ -2852,6 +2856,7 @@ shaka.hls.HlsParser = class { /** * @param {number} streamId + * @param {!Map} variables * @param {!shaka.hls.Playlist} playlist * @param {function():!Array.} getUris * @param {string} responseUri diff --git a/lib/media/example_based_criteria.js b/lib/media/example_based_criteria.js index 59ea966ed0..b3fd3e969a 100644 --- a/lib/media/example_based_criteria.js +++ b/lib/media/example_based_criteria.js @@ -18,8 +18,8 @@ shaka.media.ExampleBasedCriteria = class { /** * @param {shaka.extern.Variant} example * @param {shaka.config.CodecSwitchingStrategy} codecSwitchingStrategy - * @param {shaka.media.AdaptationSetCriteria.Factory} - * adaptationSetCriteriaFactory + * @param {shaka.media.AdaptationSetCriteria.Factory + * } adaptationSetCriteriaFactory */ constructor(example, codecSwitchingStrategy, adaptationSetCriteriaFactory) { // We can't know if role and label are really important, so we don't use diff --git a/lib/media/media_source_engine.js b/lib/media/media_source_engine.js index cb93f44007..aa41b12164 100644 --- a/lib/media/media_source_engine.js +++ b/lib/media/media_source_engine.js @@ -72,17 +72,23 @@ shaka.media.MediaSourceEngine = class { /** @private {shaka.extern.TextDisplayer} */ this.textDisplayer_ = textDisplayer; - /** @private {!Object.} */ + /** + * @private {!Object.} + */ this.sourceBuffers_ = {}; - /** @private {!Object.} */ + /** + * @private {!Object.} + */ this.sourceBufferTypes_ = {}; - /** @private {!Object.} */ + /** + * @private {!Object.} + */ this.expectedEncryption_ = {}; /** @private {shaka.text.TextEngine} */ @@ -164,8 +170,10 @@ shaka.media.MediaSourceEngine = class { /** @private {?number} */ this.lastDuration_ = null; - /** @private {!Object.} */ + /** + * @private {!Object.} + */ this.tsParsers_ = {}; /** @private {?number} */ diff --git a/lib/media/preload_manager.js b/lib/media/preload_manager.js index 76f80ffe33..019390daa5 100644 --- a/lib/media/preload_manager.js +++ b/lib/media/preload_manager.js @@ -847,8 +847,8 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget { * }} * * @property {!shaka.extern.PlayerConfiguration} config - * @property {!shaka.extern.ManifestParser.PlayerInterface} - * manifestPlayerInterface + * @property {!shaka.extern.ManifestParser.PlayerInterface + * } manifestPlayerInterface * @property {!shaka.media.RegionTimeline} regionTimeline * @property {?shaka.media.QualityObserver} qualityObserver * @property {function():!shaka.drm.DrmEngine} createDrmEngine diff --git a/lib/media/quality_observer.js b/lib/media/quality_observer.js index 4a2d9e1ea2..59ee4bf580 100644 --- a/lib/media/quality_observer.js +++ b/lib/media/quality_observer.js @@ -301,40 +301,40 @@ shaka.media.QualityObserver = class extends shaka.util.FakeEventTarget { }; /** - * @typedef {{ - * mediaQuality: !shaka.extern.MediaQualityInfo, - * position: !number - * }} - * - * @description - * Identifies the position of a media quality change in the - * source buffer. - * - * @property {shaka.extern.MediaQualityInfo} !mediaQuality - * The new media quality for content after position in the source buffer. - * @property {number} !position - * A position in seconds in the source buffer - */ + * @typedef {{ + * mediaQuality: !shaka.extern.MediaQualityInfo, + * position: !number + * }} + * + * @description + * Identifies the position of a media quality change in the + * source buffer. + * + * @property {!shaka.extern.MediaQualityInfo} mediaQuality + * The new media quality for content after position in the source buffer. + * @property {!number} position + * A position in seconds in the source buffer + */ shaka.media.QualityObserver.QualityChangePosition; /** - * @typedef {{ - * qualityChangePositions: - * !Array., - * currentQuality: ?shaka.extern.MediaQualityInfo, - * contentType: !string - * }} - * - * @description - * Contains media quality information for a specific content type - * e.g. video or audio. - * - * @property {!Array.} - * qualityChangePositions - * Quality changes ordered by position ascending. - * @property {?shaka.media.MediaQualityInfo} currentMediaQuality - * The media quality at the playhead position. - * @property {string} contentType - * The contentType e.g. 'video' or 'audio' - */ + * @typedef {{ + * qualityChangePositions: + * !Array., + * currentQuality: ?shaka.extern.MediaQualityInfo, + * contentType: !string + * }} + * + * @description + * Contains media quality information for a specific content type + * e.g. video or audio. + * + * @property {!Array. + * } qualityChangePositions + * Quality changes ordered by position ascending. + * @property {?shaka.media.MediaQualityInfo} currentMediaQuality + * The media quality at the playhead position. + * @property {string} contentType + * The contentType e.g. 'video' or 'audio' + */ shaka.media.QualityObserver.ContentTypeState; diff --git a/lib/media/segment_prefetch.js b/lib/media/segment_prefetch.js index 2ea7206a8d..76f89f8469 100644 --- a/lib/media/segment_prefetch.js +++ b/lib/media/segment_prefetch.js @@ -41,14 +41,14 @@ shaka.media.SegmentPrefetch = class { /** * @private {!Map.< - * !(shaka.media.SegmentReference), + * !shaka.media.SegmentReference, * !shaka.media.SegmentPrefetchOperation>} */ this.segmentPrefetchMap_ = new Map(); /** * @private {!Map.< - * !(shaka.media.InitSegmentReference), + * !shaka.media.InitSegmentReference, * !shaka.media.SegmentPrefetchOperation>} */ this.initSegmentPrefetchMap_ = new Map(); @@ -173,8 +173,8 @@ shaka.media.SegmentPrefetch = class { /** * Get the result of prefetched segment if already exists. - * @param {!(shaka.media.SegmentReference|shaka.media.InitSegmentReference)} - * reference + * @param {!(shaka.media.SegmentReference| + * shaka.media.InitSegmentReference)} reference * @param {?function(BufferSource):!Promise=} streamDataCallback * @return {?shaka.net.NetworkingEngine.PendingRequest} op * @public @@ -225,6 +225,9 @@ shaka.media.SegmentPrefetch = class { /** * Clear All Helper + * @param {!Map} map + * @template T SegmentReference or InitSegmentReference * @private */ clearMap_(map) { @@ -355,8 +358,8 @@ shaka.media.SegmentPrefetch = class { /** * Remove a segment from prefetch map and abort it. - * @param {!(shaka.media.SegmentReference|shaka.media.InitSegmentReference)} - * reference + * @param {!(shaka.media.SegmentReference| + * shaka.media.InitSegmentReference)} reference * @private */ abortPrefetchedSegment_(reference) { @@ -384,6 +387,7 @@ shaka.media.SegmentPrefetch = class { /** * The prefix of the logs that are created in this class. + * @param {shaka.extern.Stream} stream * @return {string} * @private */ @@ -419,10 +423,10 @@ shaka.media.SegmentPrefetchOperation = class { } /** - * Fetch a segments + * Fetch segments * - * @param {!(shaka.media.SegmentReference|shaka.media.InitSegmentReference)} - * reference + * @param {!(shaka.media.SegmentReference| + * shaka.media.InitSegmentReference)} reference * @param {!shaka.extern.Stream} stream * @return {!Promise} * @public diff --git a/lib/media/streaming_engine.js b/lib/media/streaming_engine.js index b421b3afb1..7c9e8ad612 100644 --- a/lib/media/streaming_engine.js +++ b/lib/media/streaming_engine.js @@ -2421,8 +2421,8 @@ shaka.media.StreamingEngine = class { * Fetches the given segment. * * @param {!shaka.media.StreamingEngine.MediaState_} mediaState - * @param {(!shaka.media.InitSegmentReference|!shaka.media.SegmentReference)} - * reference + * @param {(!shaka.media.InitSegmentReference| + * !shaka.media.SegmentReference)} reference * @param {?function(BufferSource):!Promise=} streamDataCallback * * @return {!Promise.} @@ -2462,9 +2462,9 @@ shaka.media.StreamingEngine = class { /** * Fetches the given segment. * + * @param {(!shaka.media.InitSegmentReference| + * !shaka.media.SegmentReference)} reference * @param {!shaka.extern.Stream} stream - * @param {(!shaka.media.InitSegmentReference|!shaka.media.SegmentReference)} - * reference * @param {?function(BufferSource):!Promise=} streamDataCallback * @param {boolean=} isPreload * @@ -2482,9 +2482,9 @@ shaka.media.StreamingEngine = class { /** * Fetches the given segment. * + * @param {(!shaka.media.InitSegmentReference| + * !shaka.media.SegmentReference)} reference * @param {!shaka.extern.Stream} stream - * @param {(!shaka.media.InitSegmentReference|!shaka.media.SegmentReference)} - * reference * @param {?function(BufferSource):!Promise} streamDataCallback * @param {shaka.extern.RetryParameters} retryParameters * @param {!shaka.net.NetworkingEngine} netEngine @@ -2869,8 +2869,8 @@ shaka.media.StreamingEngine = class { * @property {function(!shaka.media.SegmentReference, * !shaka.extern.Stream)} onSegmentAppended * Called after a segment is successfully appended to a MediaSource. - * @property - * {function(!number, !shaka.media.InitSegmentReference)} onInitSegmentAppended + * @property {function(!number, + * !shaka.media.InitSegmentReference)} onInitSegmentAppended * Called when an init segment is appended to a MediaSource. * @property {!function(shaka.util.ManifestParserUtils.ContentType, * !BufferSource):Promise} beforeAppendSegment diff --git a/lib/mss/content_protection.js b/lib/mss/content_protection.js index b6cf676ea2..1bde8f89d3 100644 --- a/lib/mss/content_protection.js +++ b/lib/mss/content_protection.js @@ -77,7 +77,7 @@ shaka.mss.ContentProtection = class { static getInitDataFromPro_(element, systemID, keyId) { const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils; const data = Uint8ArrayUtils.fromBase64( - /** @type{string} */ (shaka.util.TXml.getTextContents(element))); + /** @type {string} */ (shaka.util.TXml.getTextContents(element))); const systemId = Uint8ArrayUtils.fromHex(systemID.replace(/-/g, '')); const keyIds = new Set(); const psshVersion = 0; diff --git a/lib/net/networking_engine.js b/lib/net/networking_engine.js index 59f4c34616..77928a099b 100644 --- a/lib/net/networking_engine.js +++ b/lib/net/networking_engine.js @@ -53,8 +53,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget { * of whether the switching is allowed. * @param {shaka.net.NetworkingEngine.OnHeadersReceived=} onHeadersReceived * Called when the headers are received for a download. - * @param {shaka.net.NetworkingEngine.OnDownloadCompleted=} - * onDownloadCompleted Called when a download completed successfully. + * @param {shaka.net.NetworkingEngine.OnDownloadCompleted= + * } onDownloadCompleted Called when a download completed successfully. * @param {shaka.net.NetworkingEngine.OnDownloadFailed=} onDownloadFailed * Called when a download fails, for any reason. * @param {shaka.net.NetworkingEngine.OnRequest=} onRequest @@ -471,8 +471,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget { * @param {shaka.net.NetworkingEngine.RequestType} type * @param {shaka.extern.Request} request * @param {(shaka.extern.RequestContext|undefined)} context - * @param {shaka.net.NetworkingEngine.NumBytesRemainingClass} - * numBytesRemainingObj + * @param {shaka.net.NetworkingEngine.NumBytesRemainingClass + * } numBytesRemainingObj * @return {!shaka.extern.IAbortableOperation.< * shaka.net.NetworkingEngine.ResponseAndGotProgress>} * @private @@ -495,8 +495,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget { * @param {!shaka.net.Backoff} backoff * @param {number} index * @param {?shaka.util.Error} lastError - * @param {shaka.net.NetworkingEngine.NumBytesRemainingClass} - * numBytesRemainingObj + * @param {shaka.net.NetworkingEngine.NumBytesRemainingClass + * } numBytesRemainingObj * @return {!shaka.extern.IAbortableOperation.< * shaka.net.NetworkingEngine.ResponseAndGotProgress>} * @private @@ -735,8 +735,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget { /** * @param {shaka.net.NetworkingEngine.RequestType} type - * @param {shaka.net.NetworkingEngine.ResponseAndGotProgress} - * responseAndGotProgress + * @param {shaka.net.NetworkingEngine.ResponseAndGotProgress + * } responseAndGotProgress * @param {shaka.extern.RequestContext=} context * @return {!shaka.extern.IAbortableOperation.< * shaka.net.NetworkingEngine.ResponseAndGotProgress>} @@ -867,8 +867,8 @@ class extends shaka.util.AbortableOperation { * undone. abort() should return a Promise which is resolved when the * underlying operation has been aborted. The returned Promise should * never be rejected. - * @param {shaka.net.NetworkingEngine.NumBytesRemainingClass} - * numBytesRemainingObj + * @param {shaka.net.NetworkingEngine.NumBytesRemainingClass + * } numBytesRemainingObj */ constructor(promise, onAbort, numBytesRemainingObj) { super(promise, onAbort); diff --git a/lib/offline/indexeddb/db_operation.js b/lib/offline/indexeddb/db_operation.js index 7c334b18ea..47fd15c1e9 100644 --- a/lib/offline/indexeddb/db_operation.js +++ b/lib/offline/indexeddb/db_operation.js @@ -62,8 +62,8 @@ shaka.offline.indexeddb.DBOperation = class { /** * Calls the given callback for each entry in the database. * - * @param {function(!IDBKeyType, T, !IDBCursorWithValue=):(Promise|undefined)} - * callback + * @param {function(!IDBKeyType, T, !IDBCursorWithValue=): + * (Promise|undefined)} callback * @return {!Promise} * @template T */ diff --git a/lib/offline/storage.js b/lib/offline/storage.js index 2e1ceebaed..3f046d6103 100644 --- a/lib/offline/storage.js +++ b/lib/offline/storage.js @@ -1503,7 +1503,6 @@ shaka.offline.Storage = class { try { goog.asserts.assert( this.networkingEngine_, 'Need networking engine.'); - // eslint-disable-next-line require-atomic-updates mimeType = await shaka.net.NetworkingUtils.getMimeType(uri, this.networkingEngine_, this.config_.streaming.retryParameters); diff --git a/lib/player.js b/lib/player.js index 17ebdc1b6a..392e58ae57 100644 --- a/lib/player.js +++ b/lib/player.js @@ -6302,7 +6302,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget { try { goog.asserts.assert( this.networkingEngine_, 'Need networking engine.'); - // eslint-disable-next-line require-atomic-updates mimeType = await shaka.net.NetworkingUtils.getMimeType(uri, this.networkingEngine_, this.config_.streaming.retryParameters); @@ -8363,7 +8362,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5; * @define {string} A version number taken from git at compile time. * @export */ -// eslint-disable-next-line no-useless-concat, max-len +// eslint-disable-next-line no-useless-concat shaka.Player.version = 'v4.12.0' + '-uncompiled'; // x-release-please-version // Initialize the deprecation system using the version string we just set diff --git a/lib/polyfill/video_play_promise.js b/lib/polyfill/video_play_promise.js index e03fc921ea..69a9e9290e 100644 --- a/lib/polyfill/video_play_promise.js +++ b/lib/polyfill/video_play_promise.js @@ -27,7 +27,6 @@ shaka.polyfill.VideoPlayPromise = class { const originalPlay = HTMLMediaElement.prototype.play; // eslint-disable-next-line no-restricted-syntax HTMLMediaElement.prototype.play = function() { - // eslint-disable-next-line no-restricted-syntax const p = originalPlay.apply(this); if (p) { // This browser is returning a Promise from play(). diff --git a/lib/text/cue.js b/lib/text/cue.js index 69acc94b8a..dc37b3585c 100644 --- a/lib/text/cue.js +++ b/lib/text/cue.js @@ -764,6 +764,7 @@ shaka.text.Cue = class { /** * @param {string} value * @param {string} defaultValue + * @return {string} * @private */ static getOrDefault_(value, defaultValue) { diff --git a/lib/text/stub_text_displayer.js b/lib/text/stub_text_displayer.js index 2c8ffffb3b..8c55bc3d2e 100644 --- a/lib/text/stub_text_displayer.js +++ b/lib/text/stub_text_displayer.js @@ -7,11 +7,11 @@ goog.provide('shaka.text.StubTextDisplayer'); /** -* A stub text displayer plugin that does nothing -* -* @implements {shaka.extern.TextDisplayer} -* @export -*/ + * A stub text displayer plugin that does nothing + * + * @implements {shaka.extern.TextDisplayer} + * @export + */ shaka.text.StubTextDisplayer = class { /** * @override diff --git a/lib/text/text_engine.js b/lib/text/text_engine.js index 270f8d0cd3..0842b13c8f 100644 --- a/lib/text/text_engine.js +++ b/lib/text/text_engine.js @@ -63,7 +63,8 @@ shaka.text.TextEngine = class { * re-fetching the video segments they were embedded in. * Structure of closed caption map: * closed caption id -> {start and end time -> cues} - * @private {!Map.>>} */ + * @private {!Map.>>} + */ this.closedCaptionsMap_ = new Map(); } diff --git a/lib/text/ui_text_displayer.js b/lib/text/ui_text_displayer.js index df6337faa0..bdd3d8ec85 100644 --- a/lib/text/ui_text_displayer.js +++ b/lib/text/ui_text_displayer.js @@ -926,7 +926,7 @@ shaka.text.UITextDisplayer = class { * @param {HTMLElement} videoContainer * @return {string} * @private - */ + */ static convertLengthValue_(lengthValue, cue, videoContainer) { const lengthValueInfo = shaka.text.UITextDisplayer.getLengthValueInfo_(lengthValue); @@ -958,7 +958,7 @@ shaka.text.UITextDisplayer = class { * @return {string} * * @private - * */ + */ static getAbsoluteLengthInPixels_(value, cue, videoContainer) { const containerHeight = videoContainer.clientHeight; diff --git a/lib/util/cmcd_manager.js b/lib/util/cmcd_manager.js index 4f3969c733..48507797cb 100644 --- a/lib/util/cmcd_manager.js +++ b/lib/util/cmcd_manager.js @@ -44,8 +44,8 @@ shaka.util.CmcdManager = class { this.playbackStarted_ = false; /** - * @private {boolean} - */ + * @private {boolean} + */ this.buffering_ = true; /** @@ -91,7 +91,7 @@ shaka.util.CmcdManager = class { /** * Set media element and setup event listeners * @param {HTMLMediaElement} mediaElement The video element - */ + */ setMediaElement(mediaElement) { this.video_ = mediaElement; this.setupMSDEventListeners_(); @@ -446,7 +446,7 @@ shaka.util.CmcdManager = class { /** * Setup event listeners for msd calculation * @private - */ + */ setupMSDEventListeners_() { const onPlaybackPlay = () => this.onPlaybackPlay_(); this.eventManager_.listenOnce( @@ -568,6 +568,7 @@ shaka.util.CmcdManager = class { * * @param {shaka.extern.RequestContext} context * The request context + * @return {shaka.util.CmcdManager.ObjectType|undefined} * @private */ getObjectType_(context) { @@ -817,7 +818,7 @@ shaka.util.CmcdManager = class { /** * Get the highest bandwidth for a given type. * - * @param {string} type + * @param {shaka.util.CmcdManager.ObjectType|undefined} type * @return {number} * @private */ diff --git a/lib/util/config_utils.js b/lib/util/config_utils.js index b5d4024cc4..3baf801f06 100644 --- a/lib/util/config_utils.js +++ b/lib/util/config_utils.js @@ -125,7 +125,7 @@ shaka.util.ConfigUtils = class { let last = configObject; let searchIndex = 0; let nameStart = 0; - while (true) { // eslint-disable-line no-constant-condition + while (true) { const idx = fieldName.indexOf('.', searchIndex); if (idx < 0) { break; diff --git a/lib/util/content_steering_manager.js b/lib/util/content_steering_manager.js index 211fbd2ffe..9f39d0ee1b 100644 --- a/lib/util/content_steering_manager.js +++ b/lib/util/content_steering_manager.js @@ -329,7 +329,7 @@ shaka.util.ContentSteeringManager = class { * * @property {string} VERSION * @property {number} TTL - * @property {string RELOAD-URI + * @property {string} RELOAD-URI * @property {!Array.} PATHWAY-PRIORITY * @property {!Array.< * shaka.util.ContentSteeringManager.PathwayClone>} PATHWAY-CLONES diff --git a/lib/util/data_view_reader.js b/lib/util/data_view_reader.js index fb7db36b31..6bc7a300a2 100644 --- a/lib/util/data_view_reader.js +++ b/lib/util/data_view_reader.js @@ -13,9 +13,9 @@ goog.require('shaka.util.StringUtils'); /** - * @summary DataViewReader abstracts a DataView object. - * @export - */ + * @summary DataViewReader abstracts a DataView object. + * @export + */ shaka.util.DataViewReader = class { /** * @param {BufferSource} data diff --git a/lib/util/fairplay_utils.js b/lib/util/fairplay_utils.js index 4e0529fd97..dc8b71c9cb 100644 --- a/lib/util/fairplay_utils.js +++ b/lib/util/fairplay_utils.js @@ -138,6 +138,7 @@ shaka.util.FairPlayUtils = class { * @param {!Uint8Array} initData * @param {string} initDataType * @param {?shaka.extern.DrmInfo} drmInfo + * @return {!Uint8Array} * @private */ static basicInitDataTransform_(initData, initDataType, drmInfo) { @@ -158,6 +159,7 @@ shaka.util.FairPlayUtils = class { * @param {!Uint8Array} initData * @param {string} initDataType * @param {?shaka.extern.DrmInfo} drmInfo + * @return {!Uint8Array} * @export */ static verimatrixInitDataTransform(initData, initDataType, drmInfo) { @@ -171,6 +173,7 @@ shaka.util.FairPlayUtils = class { * @param {!Uint8Array} initData * @param {string} initDataType * @param {?shaka.extern.DrmInfo} drmInfo + * @return {!Uint8Array} * @export */ static ezdrmInitDataTransform(initData, initDataType, drmInfo) { @@ -191,6 +194,7 @@ shaka.util.FairPlayUtils = class { * @param {!Uint8Array} initData * @param {string} initDataType * @param {?shaka.extern.DrmInfo} drmInfo + * @return {!Uint8Array} * @export */ static conaxInitDataTransform(initData, initDataType, drmInfo) { @@ -221,6 +225,7 @@ shaka.util.FairPlayUtils = class { * @param {!Uint8Array} initData * @param {string} initDataType * @param {?shaka.extern.DrmInfo} drmInfo + * @return {!Uint8Array} * @export */ static expressplayInitDataTransform(initData, initDataType, drmInfo) { diff --git a/lib/util/mp4_generator.js b/lib/util/mp4_generator.js index 92043d565b..89115522b8 100644 --- a/lib/util/mp4_generator.js +++ b/lib/util/mp4_generator.js @@ -1081,6 +1081,7 @@ shaka.util.Mp4Generator = class { /** * Generate a MDAT box * + * @param {shaka.util.Mp4Generator.StreamInfo} streamInfo * @return {!Uint8Array} * @private */ diff --git a/lib/util/object_utils.js b/lib/util/object_utils.js index 716693b6c5..454542b6dd 100644 --- a/lib/util/object_utils.js +++ b/lib/util/object_utils.js @@ -22,7 +22,11 @@ shaka.util.ObjectUtils = class { const seenObjects = new WeakSet(); // This recursively clones the value |val|, using the captured variable // |seenObjects| to track the objects we have already cloned. - /** @suppress {strictMissingProperties} */ + /** + * @param {*} val + * @return {*} + * @suppress {strictMissingProperties} + */ const clone = (val) => { switch (typeof val) { case 'undefined': diff --git a/lib/util/periods.js b/lib/util/periods.js index 0964931738..6e1729dee8 100644 --- a/lib/util/periods.js +++ b/lib/util/periods.js @@ -93,7 +93,7 @@ shaka.util.PeriodCombiner = class { * @return {!Array.} * * @export - */ + */ getTextStreams() { // Return a copy of the array because makeTextStreamsForClosedCaptions // may make changes to the contents of the array. Those changes should not diff --git a/lib/util/platform.js b/lib/util/platform.js index a9803d4758..b5a59a60b6 100644 --- a/lib/util/platform.js +++ b/lib/util/platform.js @@ -331,6 +331,7 @@ shaka.util.Platform = class { /** * Check if the current platform is Playstation 4. + * @return {boolean} */ static isPS4() { return shaka.util.Platform.userAgentContains_('PlayStation 4'); @@ -338,6 +339,7 @@ shaka.util.Platform = class { /** * Check if the current platform is Hisense. + * @return {boolean} */ static isHisense() { return shaka.util.Platform.userAgentContains_('Hisense') || @@ -346,6 +348,7 @@ shaka.util.Platform = class { /** * Check if the current platform is Virgin Media device. + * @return {boolean} */ static isVirginMedia() { return shaka.util.Platform.userAgentContains_('VirginMedia'); @@ -353,6 +356,7 @@ shaka.util.Platform = class { /** * Check if the current platform is Orange. + * @return {boolean} */ static isOrange() { return shaka.util.Platform.userAgentContains_('SOPOpenBrowser'); @@ -360,6 +364,7 @@ shaka.util.Platform = class { /** * Check if the current platform is SkyQ STB. + * @return {boolean} */ static isSkyQ() { return shaka.util.Platform.userAgentContains_('Sky_STB'); @@ -795,7 +800,6 @@ shaka.util.Platform = class { maxResolution.height = 1080; } } else if (Platform.isHisense()) { - // eslint-disable-next-line new-cap if (window.Hisense_Get4KSupportState && // eslint-disable-next-line new-cap window.Hisense_Get4KSupportState()) { diff --git a/lib/util/player_configuration.js b/lib/util/player_configuration.js index 0dc1b4669f..aa1d648da8 100644 --- a/lib/util/player_configuration.js +++ b/lib/util/player_configuration.js @@ -281,6 +281,11 @@ shaka.util.PlayerConfiguration = class { shaka.util.Platform.isTizen(), }; + const safariVersion = shaka.util.Platform.safariVersion(); + if (safariVersion && safariVersion >= 17) { + streaming.infiniteLiveStreamDuration = true; + } + // WebOS, Tizen, Chromecast and Hisense have long hardware pipelines // that respond slowly to seeking. // Therefore we should not seek when we detect a stall diff --git a/lib/util/pssh.js b/lib/util/pssh.js index 185c794edc..f2fa7a8c1f 100644 --- a/lib/util/pssh.js +++ b/lib/util/pssh.js @@ -144,6 +144,34 @@ shaka.util.Pssh = class { return psshBox; } + /** + * Returns just the data portion of a single PSSH + * + * @param {!Uint8Array} pssh + * @return {!Uint8Array} + */ + static getPsshData(pssh) { + let offset = 8; // Box size and type fields + + /** @type {!DataView} */ + const view = shaka.util.BufferUtils.toDataView(pssh); + + // Read version + const version = view.getUint8(offset); + + // Version (1), flags (3), system ID (16) + offset += 20; + + if (version > 0) { + // Key ID count (4) and All key IDs (16*count) + offset += 4 + (16 * view.getUint32(offset)); + } + + // Data size + offset += 4; + + return shaka.util.BufferUtils.toUint8(view, offset); + } /** * Normalise the initData array. This is to apply browser specific diff --git a/lib/util/string_utils.js b/lib/util/string_utils.js index e52fba0ce1..42d87d5617 100644 --- a/lib/util/string_utils.js +++ b/lib/util/string_utils.js @@ -334,7 +334,10 @@ shaka.util.StringUtils = class { /** @private {!shaka.util.Lazy.} */ shaka.util.StringUtils.fromCharCodeImpl_ = new shaka.util.Lazy(() => { - /** @param {number} size @return {boolean} */ + /** + * @param {number} size + * @return {boolean} + */ const supportsChunkSize = (size) => { try { // The compiler will complain about suspicious value if this isn't @@ -344,7 +347,6 @@ shaka.util.StringUtils.fromCharCodeImpl_ = new shaka.util.Lazy(() => { // This can't use the spread operator, or it blows up on Xbox One. // So we use apply() instead, which is normally not allowed. // See issue #2186 for more details. - // eslint-disable-next-line no-restricted-syntax const foo = String.fromCharCode.apply(null, buffer); goog.asserts.assert(foo, 'Should get value'); return foo.length > 0; // Actually use "foo", so it's not compiled out. @@ -367,7 +369,6 @@ shaka.util.StringUtils.fromCharCodeImpl_ = new shaka.util.Lazy(() => { // This can't use the spread operator, or it blows up on Xbox One. // So we use apply() instead, which is normally not allowed. // See issue #2186 for more details. - // eslint-disable-next-line no-restricted-syntax ret += String.fromCharCode.apply(null, subArray); // Issue #2186 } return ret; diff --git a/lib/util/tXml.js b/lib/util/tXml.js index c2b908e3e6..5f698b3c9c 100644 --- a/lib/util/tXml.js +++ b/lib/util/tXml.js @@ -13,7 +13,7 @@ goog.require('shaka.log'); /** * This code is a modified version of the tXml library. * - * @author: Tobias Nickel + * @author Tobias Nickel * created: 06.04.2015 * https://github.com/TobiasNickel/tXml */ @@ -57,6 +57,7 @@ shaka.util.TXml = class { * Parse some data * @param {string} xmlString * @param {string=} expectedRootElemName + * @param {boolean=} includeParent * @return {shaka.extern.xml.Node | null} */ static parseXmlString(xmlString, expectedRootElemName, @@ -132,9 +133,12 @@ shaka.util.TXml = class { /** * parsing a list of entries + * @param {string} tagName + * @param {boolean=} preserveSpace + * @return {!Array} */ function parseChildren(tagName, preserveSpace = false) { - /** @type {Array.} */ + /** @type {!Array.} */ const children = []; while (S[pos]) { if (S.charCodeAt(pos) == openBracketCC) { @@ -152,7 +156,6 @@ shaka.util.TXml = class { indexOfCloseTag = closeTag.indexOf(shortTag); } } - // eslint-disable-next-line no-restricted-syntax if (indexOfCloseTag == -1) { const parsedText = S.substring(0, pos).split('\n'); throw new Error( @@ -229,7 +232,8 @@ shaka.util.TXml = class { } /** - * returns the text outside of texts until the first '<' + * returns the text outside of texts until the first '<' + * @return {string} */ function parseText() { const start = pos; @@ -556,8 +560,9 @@ shaka.util.TXml = class { const schemaNS = shaka.util.TXml.getKnownNameSpace(ns); const found = []; if (elem.children) { + const tagName = schemaNS ? `${schemaNS}:${name}` : name; for (const child of elem.children) { - if (child && child.tagName === `${schemaNS}:${name}`) { + if (child && child.tagName === tagName) { found.push(child); } } @@ -858,6 +863,7 @@ shaka.util.TXml = class { * @param {!Array} nodes * @param {!string} attribute * @param {!number} value + * @return {?number} * @private */ static nodePositionByAttribute_(nodes, attribute, value) { diff --git a/package-lock.json b/package-lock.json index 035bd8adec..5ad5bd8379 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,11 +28,13 @@ "cspell": "^8.17.1", "dialog-polyfill": "^0.5.6", "es6-promise-polyfill": "^1.2.0", - "eslint": "^8.57.1", - "eslint-config-google": "^0.14.0", + "eslint": "^9.18.0", + "eslint-config-google": "github:google/eslint-config-google#3ae571a", + "eslint-plugin-jsdoc": "^50.6.1", "eslint-plugin-shaka-rules": "file:./build/eslint-plugin-shaka-rules", "esprima": "^4.0.1", "fontfaceonload": "^1.0.2", + "globals": "^15.14.0", "google-closure-compiler-java": "^20240317.0.0", "google-closure-deps": "^20230802.0.0", "google-closure-library": "^20221102.0.0", @@ -1050,6 +1052,16 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", @@ -1642,6 +1654,16 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", @@ -2233,6 +2255,21 @@ "node": ">=18.0" } }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", + "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.1.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -2262,17 +2299,45 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2280,65 +2345,95 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@eslint/js": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18.18.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -2355,13 +2450,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -2933,6 +3034,19 @@ "node": ">= 8" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", @@ -2976,6 +3090,20 @@ "@types/node": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", @@ -3025,13 +3153,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -3196,6 +3317,16 @@ "lodash": "^4.17.14" } }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3929,6 +4060,16 @@ "dev": true, "license": "MIT" }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/compress-commons": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", @@ -4135,10 +4276,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4604,18 +4746,6 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serialize": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", @@ -4802,6 +4932,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true, + "license": "MIT" + }, "node_modules/es6-promise-polyfill": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz", @@ -4833,66 +4970,68 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-google": { "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "resolved": "git+ssh://git@github.com/google/eslint-config-google.git#3ae571a6a255ee5b03f208295dd964c5cdfba739", "dev": true, "license": "Apache-2.0", "engines": { @@ -4902,14 +5041,102 @@ "eslint": ">=5.16.0" } }, + "node_modules/eslint-plugin-jsdoc": { + "version": "50.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.1.tgz", + "integrity": "sha512-UWyaYi6iURdSfdVVqvfOs2vdCVz0J40O/z/HTsv2sFjdjmdlUI/qlKLOTmwbPQ2tAfQnE5F9vqx+B+poF71DBQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.49.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.6", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/eslint-plugin-shaka-rules": { "resolved": "build/eslint-plugin-shaka-rules", "link": true }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4917,7 +5144,7 @@ "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -4997,6 +5224,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/eslint/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -5014,20 +5267,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/eslint/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^0.20.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=16" } }, "node_modules/eslint/node_modules/has-flag": { @@ -5099,32 +5350,32 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -5779,12 +6030,16 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { @@ -5857,13 +6112,6 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -6437,16 +6685,6 @@ "node": ">=8" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -6717,6 +6955,16 @@ "node": ">=8.15.0" } }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/jsdoc/node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", @@ -7991,6 +8239,20 @@ "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", "dev": true }, + "node_modules/parse-imports": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", + "dev": true, + "license": "Apache-2.0 AND MIT", + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -8930,6 +9192,13 @@ "node": ">=8" } }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true, + "license": "ISC" + }, "node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -9407,6 +9676,23 @@ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", "dev": true }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/table": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", @@ -9481,12 +9767,6 @@ "node": ">=8" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, "node_modules/through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", @@ -9678,10 +9958,11 @@ } }, "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -10991,6 +11272,14 @@ "@babel/helper-replace-supers": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, "@babel/plugin-transform-computed-properties": { @@ -11402,6 +11691,14 @@ "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, "@babel/types": { @@ -11888,6 +12185,17 @@ "integrity": "sha512-LMvReIndW1ckvemElfDgTt282fb2C3C/ZXfsm0pJsTV5ZmtdelCHwzmgSBmY5fDr7D66XDp8EurotSE0K6BTvw==", "dev": true }, + "@es-joy/jsdoccomment": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", + "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", + "dev": true, + "requires": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.1.0" + } + }, "@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -11903,16 +12211,36 @@ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true }, + "@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "requires": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + } + }, + "@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.15" + } + }, "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -11921,37 +12249,57 @@ }, "dependencies": { "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true } } }, "@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", "dev": true }, - "@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true + }, + "@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + } + }, + "@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true + }, + "@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "requires": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "dependencies": { + "@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true + } } }, "@humanwhocodes/module-importer": { @@ -11960,10 +12308,10 @@ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true }, - "@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -12405,6 +12753,12 @@ "fastq": "^1.6.0" } }, + "@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true + }, "@socket.io/component-emitter": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", @@ -12441,6 +12795,18 @@ "@types/node": "*" } }, + "@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "@types/linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", @@ -12490,12 +12856,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -12632,6 +12992,12 @@ } } }, + "are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -13188,6 +13554,12 @@ } } }, + "comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true + }, "compress-commons": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", @@ -13364,9 +13736,9 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -13692,15 +14064,6 @@ "path-type": "^4.0.0" } }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "dom-serialize": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", @@ -13852,6 +14215,12 @@ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true }, + "es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true + }, "es6-promise-polyfill": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz", @@ -13877,49 +14246,45 @@ "dev": true }, "eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "dependencies": { "ansi-styles": { @@ -13962,6 +14327,21 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true + }, + "file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "requires": { + "flat-cache": "^4.0.0" + } + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -13972,13 +14352,14 @@ "path-exists": "^4.0.0" } }, - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "requires": { - "type-fest": "^0.20.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" } }, "has-flag": { @@ -14022,29 +14403,80 @@ "requires": { "has-flag": "^4.0.0" } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true } } }, "eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "version": "git+ssh://git@github.com/google/eslint-config-google.git#3ae571a6a255ee5b03f208295dd964c5cdfba739", "dev": true, + "from": "eslint-config-google@github:google/eslint-config-google#3ae571a", "requires": {} }, + "eslint-plugin-jsdoc": { + "version": "50.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.1.tgz", + "integrity": "sha512-UWyaYi6iURdSfdVVqvfOs2vdCVz0J40O/z/HTsv2sFjdjmdlUI/qlKLOTmwbPQ2tAfQnE5F9vqx+B+poF71DBQ==", + "dev": true, + "requires": { + "@es-joy/jsdoccomment": "~0.49.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.6", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + } + } + }, "eslint-plugin-shaka-rules": { "version": "file:build/eslint-plugin-shaka-rules" }, "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -14058,14 +14490,22 @@ "dev": true }, "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "requires": { - "acorn": "^8.9.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true + } } }, "esprima": { @@ -14556,9 +14996,9 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "dev": true }, "globby": { @@ -14618,12 +15058,6 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -15041,12 +15475,6 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -15275,6 +15703,12 @@ } } }, + "jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", + "dev": true + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -16257,6 +16691,16 @@ "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", "dev": true }, + "parse-imports": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", + "dev": true, + "requires": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + } + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -16943,6 +17387,12 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, "slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -17312,6 +17762,16 @@ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", "dev": true }, + "synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "requires": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + } + }, "table": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", @@ -17375,12 +17835,6 @@ "minimatch": "^3.0.4" } }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", @@ -17534,9 +17988,9 @@ "dev": true }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true }, "tunnel-agent": { diff --git a/package.json b/package.json index 81d2bb0166..de49f4ad61 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,13 @@ "cspell": "^8.17.1", "dialog-polyfill": "^0.5.6", "es6-promise-polyfill": "^1.2.0", - "eslint": "^8.57.1", - "eslint-config-google": "^0.14.0", + "eslint": "^9.18.0", + "eslint-config-google": "github:google/eslint-config-google#3ae571a", + "eslint-plugin-jsdoc": "^50.6.1", "eslint-plugin-shaka-rules": "file:./build/eslint-plugin-shaka-rules", "esprima": "^4.0.1", "fontfaceonload": "^1.0.2", + "globals": "^15.14.0", "google-closure-compiler-java": "^20240317.0.0", "google-closure-deps": "^20230802.0.0", "google-closure-library": "^20221102.0.0", diff --git a/shaka-player.uncompiled.js b/shaka-player.uncompiled.js index 10ef0a121c..b80c23c840 100644 --- a/shaka-player.uncompiled.js +++ b/shaka-player.uncompiled.js @@ -117,6 +117,7 @@ goog.require('shaka.ui.VolumeBar'); goog.require('shaka.ui.VRManager'); goog.require('shaka.ui.VRUtils'); goog.require('shaka.ui.VRWebgl'); +goog.require('shaka.ui.Watermark'); goog.require('shaka.util.Dom'); goog.require('shaka.util.Error'); goog.require('shaka.util.FairPlayUtils'); diff --git a/test/cast/cast_receiver_integration.js b/test/cast/cast_receiver_integration.js index f86b0df17e..b929879844 100644 --- a/test/cast/cast_receiver_integration.js +++ b/test/cast/cast_receiver_integration.js @@ -363,17 +363,21 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => { function waitForUpdateMessageWrapper(prototype, name, methodName) { pendingWaitWrapperCalls += 1; const original = prototype[methodName]; - // eslint-disable-next-line no-restricted-syntax - prototype[methodName] = /** @this {Object} @return {*} */ async function() { - pendingWaitWrapperCalls -= 1; - shaka.log.debug( - 'Waiting for update message before calling ' + - name + '.' + methodName + '...'); - const originalArguments = Array.from(arguments); - await waitForUpdateMessages(); + prototype[methodName] = + /** + * @this {Object} + * @return {*} + */ // eslint-disable-next-line no-restricted-syntax - return original.apply(this, originalArguments); - }; + async function() { + pendingWaitWrapperCalls -= 1; + shaka.log.debug( + 'Waiting for update message before calling ' + + name + '.' + methodName + '...'); + const originalArguments = Array.from(arguments); + await waitForUpdateMessages(); + return original.apply(this, originalArguments); + }; toRestore.push(() => { prototype[methodName] = original; }); diff --git a/test/cea/cea708_service_unit.js b/test/cea/cea708_service_unit.js index 75ceff285a..7fd30540bb 100644 --- a/test/cea/cea708_service_unit.js +++ b/test/cea/cea708_service_unit.js @@ -64,6 +64,7 @@ describe('Cea708Service', () => { * and converts it into a CEA-708 DTVCC Packet. * @param {!Array} bytes * @param {number} pts + * @return {!shaka.cea.DtvccPacket} */ const createCea708PacketFromBytes = (bytes, pts) => { const cea708Bytes = bytes.map((code, i) => { @@ -82,6 +83,7 @@ describe('Cea708Service', () => { * and returns all the captions inside of them, using the service to decode. * @param {!shaka.cea.Cea708Service} service * @param {...!shaka.cea.DtvccPacket} packets + * @return {!Array} */ const getCaptionsFromPackets = (service, ...packets) => { const allCaptions = []; diff --git a/test/dash/dash_parser_content_protection_unit.js b/test/dash/dash_parser_content_protection_unit.js index 96934ecc8a..f5b0c46473 100644 --- a/test/dash/dash_parser_content_protection_unit.js +++ b/test/dash/dash_parser_content_protection_unit.js @@ -1029,6 +1029,109 @@ describe('DashParser ContentProtection', () => { expect(actual).toBe('www.example.com'); }); + it('pssh version 0', () => { + const laurl = [ + '', + ' ', + ' www.example.com', + ' ', + '', + ].join('\n'); + const laurlCodes = laurl.split('').map((c) => { + return c.charCodeAt(); + }); + const prBytes = new Uint16Array([ + // pr object size (in num bytes). + // + 10 for PRO size, count, and type + laurl.length * 2 + 10, 0, + // record count + 1, + // type + shaka.drm.PlayReady.PLAYREADY_RECORD_TYPES.RIGHTS_MANAGEMENT, + // record size (in num bytes) + laurl.length * 2, + // value + ].concat(laurlCodes)); + const encodedPrObject = shaka.util.Uint8ArrayUtils.toBase64(prBytes); + const data = shaka.util.Uint8ArrayUtils.fromBase64(encodedPrObject); + // PlayReady SystemID + const systemId = new Uint8Array([ + 0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40, 0x42, 0x86, + 0xab, 0x92, 0xe6, 0x5b, 0xe0, 0x88, 0x5f, 0x95, + ]); + const keyIds = new Set(); + const psshVersion = 0; + const pssh = + shaka.util.Pssh.createPssh(data, systemId, keyIds, psshVersion); + const psshBase64 = shaka.util.Uint8ArrayUtils.toBase64(pssh); + const input = { + init: null, + keyId: null, + schemeUri: '', + encryptionScheme: null, + node: + strToXml([ + '', + ' ' + psshBase64 + '', + '', + ].join('\n')), + }; + const actual = ContentProtection.getPlayReadyLicenseUrl(input); + expect(actual).toBe('www.example.com'); + }); + + it('pssh version 1', () => { + const laurl = [ + '', + ' ', + ' www.example.com', + ' ', + '', + ].join('\n'); + const laurlCodes = laurl.split('').map((c) => { + return c.charCodeAt(); + }); + const prBytes = new Uint16Array([ + // pr object size (in num bytes). + // + 10 for PRO size, count, and type + laurl.length * 2 + 10, 0, + // record count + 1, + // type + shaka.drm.PlayReady.PLAYREADY_RECORD_TYPES.RIGHTS_MANAGEMENT, + // record size (in num bytes) + laurl.length * 2, + // value + ].concat(laurlCodes)); + const encodedPrObject = shaka.util.Uint8ArrayUtils.toBase64(prBytes); + const data = shaka.util.Uint8ArrayUtils.fromBase64(encodedPrObject); + // PlayReady SystemID + const systemId = new Uint8Array([ + 0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40, 0x42, 0x86, + 0xab, 0x92, 0xe6, 0x5b, 0xe0, 0x88, 0x5f, 0x95, + ]); + const keyIds = new Set(); + keyIds.add('575e49ee6270de247bb5f814a98a6b2b'); + const psshVersion = 1; + const pssh = + shaka.util.Pssh.createPssh(data, systemId, keyIds, psshVersion); + const psshBase64 = shaka.util.Uint8ArrayUtils.toBase64(pssh); + const input = { + init: null, + keyId: null, + schemeUri: '', + encryptionScheme: null, + node: + strToXml([ + '', + ' ' + psshBase64 + '', + '', + ].join('\n')), + }; + const actual = ContentProtection.getPlayReadyLicenseUrl(input); + expect(actual).toBe('www.example.com'); + }); + it('valid dashif:Laurl node', () => { const input = { init: null, diff --git a/test/dash/dash_parser_manifest_unit.js b/test/dash/dash_parser_manifest_unit.js index 7e6af827a1..7bb830dfe5 100644 --- a/test/dash/dash_parser_manifest_unit.js +++ b/test/dash/dash_parser_manifest_unit.js @@ -2637,9 +2637,9 @@ describe('DashParser Manifest', () => { }); /** - * @param {!Array.} periods Start time of multiple periods - * @return {string} - */ + * @param {!Array.} periods Start time of multiple periods + * @return {string} + */ function buildManifestWithPeriodStartTime(periods) { const mpdTemplate = [ ` { } /** - * Creates an XML string with an xlink link to another URL, - * for use in testing recursive chains of xlink links. - * @param {number} variable - * @param {string} link - * @return {string} - * @private - */ + * Creates an XML string with an xlink link to another URL, + * for use in testing recursive chains of xlink links. + * @param {number} variable + * @param {string} link + * @return {string} + * @private + */ function makeRecursiveXMLString(variable, link) { const format = ' { 'com.abc.playready')).toBe(false); }); }); + + describe('isWisePlayKeySystem', () => { + it('should return true for WisePlay', () => { + expect(shaka.drm.DrmUtils.isWisePlayKeySystem( + 'com.huawei.wiseplay')).toBe(true); + }); + + it('should return false for non-WisePlay key systems', () => { + expect(shaka.drm.DrmUtils.isWisePlayKeySystem( + 'com.widevine.alpha')).toBe(false); + expect(shaka.drm.DrmUtils.isWisePlayKeySystem( + 'com.microsoft.playready')).toBe(false); + expect(shaka.drm.DrmUtils.isWisePlayKeySystem( + 'com.apple.fps')).toBe(false); + }); + }); }); diff --git a/test/media/media_source_engine_unit.js b/test/media/media_source_engine_unit.js index d61a7b76b8..0fbf7dbd46 100644 --- a/test/media/media_source_engine_unit.js +++ b/test/media/media_source_engine_unit.js @@ -1295,7 +1295,11 @@ describe('MediaSourceEngine', () => { initObject.set(ContentType.VIDEO, fakeVideoStream); initObject.set(ContentType.AUDIO, fakeAudioStream); - /** @suppress {visibility} */ + /** + * @param {!Map} initObject + * @suppress {visibility} + */ async function resetMSE(initObject) { await mediaSourceEngine.reset_(initObject); } diff --git a/test/media/streaming_engine_unit.js b/test/media/streaming_engine_unit.js index 7f2769e96e..1ed8345288 100644 --- a/test/media/streaming_engine_unit.js +++ b/test/media/streaming_engine_unit.js @@ -108,6 +108,7 @@ describe('StreamingEngine', () => { * @param {number=} mediaOffset The offset from 0 for the segment start times * @param {shaka.extern.aesKey=} aesKey The AES-128 key to put in * the manifest, if one should exist + * @param {boolean=} secondaryAudioVariant */ function setupVod(trickMode, mediaOffset, aesKey, secondaryAudioVariant = false) { @@ -370,6 +371,7 @@ describe('StreamingEngine', () => { * @param {number} secondPeriodStartTime * @param {number} presentationDuration * @param {shaka.extern.aesKey=} aesKey + * @param {boolean=} secondaryAudioVariant */ function setupManifest( firstPeriodStartTime, secondPeriodStartTime, presentationDuration, @@ -424,7 +426,7 @@ describe('StreamingEngine', () => { /** * Creates the StreamingEngine. - ** + * * @param {shaka.extern.StreamingConfiguration=} config Optional * configuration object which overrides the default one. */ @@ -3775,6 +3777,7 @@ describe('StreamingEngine', () => { /** * Expect buffers have been added to MSE. + * @param {boolean=} secondaryAudioVariant */ function expectHasBuffer(secondaryAudioVariant = false) { expect(mediaSourceEngine.initSegments).toEqual({ diff --git a/test/mss/mss_parser_unit.js b/test/mss/mss_parser_unit.js index 2d59b45e63..d5adcfa3c3 100644 --- a/test/mss/mss_parser_unit.js +++ b/test/mss/mss_parser_unit.js @@ -244,7 +244,7 @@ describe('MssParser Manifest', () => { fakeNetEngine.setResponseText('dummy://foo', manifestText); const config = shaka.util.PlayerConfiguration.createDefault().manifest; config.mss.manifestPreprocessorTXml = (mss) => { - /** @type{shaka.extern.xml.Node} */ (mss).children.pop(); + /** @type {shaka.extern.xml.Node} */ (mss).children.pop(); }; parser.configure(config); diff --git a/test/mss/mss_player_integration.js b/test/mss/mss_player_integration.js index d88b60c7af..2671dd54ab 100644 --- a/test/mss/mss_player_integration.js +++ b/test/mss/mss_player_integration.js @@ -22,13 +22,8 @@ describe('MSS Player', () => { /** @type {!shaka.test.Waiter} */ let waiter; - // eslint-disable-next-line max-len const url = 'https://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest'; - - // eslint-disable-next-line max-len const playreadyUrl = 'https://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest'; - - // eslint-disable-next-line max-len const playreadyLicenseUrl = 'https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(persist:false,sl:150)'; function checkPlayReadySupport() { diff --git a/test/net/http_plugin_unit.js b/test/net/http_plugin_unit.js index 245de825a0..9f549c4988 100644 --- a/test/net/http_plugin_unit.js +++ b/test/net/http_plugin_unit.js @@ -330,7 +330,7 @@ function httpPluginTests(usingFetch) { // actually insert a call to abort in the middle. // Instead, install a very elementary mock. /** @constructor */ - function NewXHRMock() { // eslint-disable-line no-inner-declarations + function NewXHRMock() { this.abort = Util.spyFunc(jasmine.createSpy('abort')); this.open = Util.spyFunc(jasmine.createSpy('open')); diff --git a/test/test/boot.js b/test/test/boot.js index ee8647f39a..d1b66dfe07 100644 --- a/test/test/boot.js +++ b/test/test/boot.js @@ -47,7 +47,11 @@ function failTestsOnNamespacedElementOrAttributeNames() { const patchElementNamespaceFunction = (name) => { // eslint-disable-next-line no-restricted-syntax const real = Element.prototype[name]; - /** @this {Element} */ + /** + * @this {Element} + * @param {string} arg + * @return {*} + */ // eslint-disable-next-line no-restricted-syntax Element.prototype[name] = function(arg) { // Ignore xml: namespaces since it's builtin. @@ -55,7 +59,6 @@ function failTestsOnNamespacedElementOrAttributeNames() { arg.includes(':')) { fail('Use namespace-aware ' + name); } - // eslint-disable-next-line no-restricted-syntax return real.apply(this, arguments); }; }; diff --git a/test/test/util/cea_utils.js b/test/test/util/cea_utils.js index e923e2f6ef..dc8353df5b 100644 --- a/test/test/util/cea_utils.js +++ b/test/test/util/cea_utils.js @@ -13,6 +13,7 @@ shaka.test.CeaUtils = class { * @param {number} startTime * @param {number} endTime * @param {string} payload + * @return {!shaka.text.Cue} */ static createDefaultCue(startTime, endTime, payload) { const cue = new shaka.text.Cue(startTime, endTime, payload); diff --git a/test/test/util/fake_media_source_engine.js b/test/test/util/fake_media_source_engine.js index b64a25d47a..06be63f6f9 100644 --- a/test/test/util/fake_media_source_engine.js +++ b/test/test/util/fake_media_source_engine.js @@ -14,8 +14,8 @@ */ shaka.test.FakeMediaSourceEngine = class { /** - * @param {!Object.} - * segmentData + * @param {!Object.} segmentData * @param {number=} drift Optional drift. Defaults to 0. */ constructor(segmentData, drift) { diff --git a/test/test/util/fake_networking_engine.js b/test/test/util/fake_networking_engine.js index f4fc804d12..17cf857ec9 100644 --- a/test/test/util/fake_networking_engine.js +++ b/test/test/util/fake_networking_engine.js @@ -17,7 +17,8 @@ shaka.test.FakeNetworkingEngine = class { /** * @private {!Map.< * string, - * shaka.test.FakeNetworkingEngine.MockedResponse>} */ + * shaka.test.FakeNetworkingEngine.MockedResponse>} + */ this.responseMap_ = new Map(); /** @private {!Map.>} */ diff --git a/test/test/util/fake_segment_prefetch.js b/test/test/util/fake_segment_prefetch.js index 115284c307..aeda4fefd9 100644 --- a/test/test/util/fake_segment_prefetch.js +++ b/test/test/util/fake_segment_prefetch.js @@ -15,14 +15,20 @@ shaka.test.FakeSegmentPrefetch = class { /** * Suppress the JSC_PRIVATE_OVERRIDE error for overriding prefetchPosTime_ + * @param {number} prefetchLimit + * @param {!shaka.extern.Stream} stream + * @param {!Object} segmentData * @suppress {visibility} */ constructor(prefetchLimit, stream, segmentData) { /** @private {number} */ this.prefetchLimit_ = prefetchLimit; - /** @private {(Set.)} */ + /** + * @private {(Set.)} + */ this.requestedReferences_ = new Set(); /** @private {shaka.extern.Stream} */ diff --git a/test/test/util/jasmine_fetch.js b/test/test/util/jasmine_fetch.js index 2b1df03533..9d7eda7271 100644 --- a/test/test/util/jasmine_fetch.js +++ b/test/test/util/jasmine_fetch.js @@ -32,8 +32,11 @@ jasmine.Fetch = class { /** @type {!Response} */ jasmine.Fetch.container_.latestResponse; - window.Headers = /** @type {function (new:Headers, - (!Array>|Headers|Object)=)} */( + window.Headers = + /** + * @type {function (new:Headers, + * (!Array>|Headers|Object)=)} + */( jasmine.Fetch.Headers); window.AbortController = /** @type {function (new:AbortController)} */ diff --git a/test/test/util/manifest_generator.js b/test/test/util/manifest_generator.js index 0016af3115..deab3e84ae 100644 --- a/test/test/util/manifest_generator.js +++ b/test/test/util/manifest_generator.js @@ -667,6 +667,7 @@ shaka.test.ManifestGenerator.Stream = class { * index and give a URI. * @param {number} segmentDuration * @param {?number=} segmentSize + * @return {shaka.test.ManifestGenerator.Stream} */ useSegmentTemplate(template, segmentDuration, segmentSize = null) { goog.asserts.assert(this.manifest_, diff --git a/test/test/util/waiter.js b/test/test/util/waiter.js index 4035a9b489..e3687c4afc 100644 --- a/test/test/util/waiter.js +++ b/test/test/util/waiter.js @@ -149,7 +149,7 @@ shaka.test.Waiter = class { * * @param {!HTMLMediaElement} mediaElement * @return {!Promise} - */ + */ waitUntilVodTransition(mediaElement) { // The name of what we're waiting for const goalName = 'manifest to be static'; diff --git a/test/transmuxer/transmuxer_integration.js b/test/transmuxer/transmuxer_integration.js index 7d5428386e..71f08cc9cf 100644 --- a/test/transmuxer/transmuxer_integration.js +++ b/test/transmuxer/transmuxer_integration.js @@ -293,7 +293,6 @@ describe('Transmuxer Player', () => { }); it('H.264+AAC in TS with rollover', async () => { - // eslint-disable-next-line max-len await player.load('/base/test/test/assets/hls-ts-rollover/playlist.m3u8'); await video.play(); expect(player.isLive()).toBe(false); diff --git a/test/ui/ui_integration.js b/test/ui/ui_integration.js index 22ae3c297c..24d008b519 100644 --- a/test/ui/ui_integration.js +++ b/test/ui/ui_integration.js @@ -607,11 +607,11 @@ describe('UI', () => { } /** - * @param {!Array.} buttons - * @param {!Array.|!Array.} choices - * @param {function(string):string|function(number):string} modifier - * @return {!Map.|!Map.} - */ + * @param {!Array.} buttons + * @param {!Array.|!Array.} choices + * @param {function(string):string|function(number):string} modifier + * @return {!Map.|!Map.} + */ function mapChoicesToButtons(buttons, choices, modifier) { expect(buttons.length).toBe(choices.length); diff --git a/test/util/periods_unit.js b/test/util/periods_unit.js index 12e814fb49..8cb8904c88 100644 --- a/test/util/periods_unit.js +++ b/test/util/periods_unit.js @@ -1990,6 +1990,7 @@ describe('PeriodCombiner', () => { * @param {number} height * @param {string} language * @param {number=} channels + * @param {!Array=} roles * @return {shaka.extern.Variant} */ function makeAVVariant(height, language, channels = 2, roles = []) { diff --git a/ui/ad_statistics_button.js b/ui/ad_statistics_button.js index 9982075bc9..7f0a114c9a 100644 --- a/ui/ad_statistics_button.js +++ b/ui/ad_statistics_button.js @@ -170,7 +170,11 @@ shaka.ui.AdStatisticsButton = class extends shaka.ui.Element { this.stateSpan_.textContent = this.localization.resolve(labelText); } - /** @private */ + /** + * @param {string} name + * @return {!HTMLElement} + * @private + */ generateComponent_(name) { const section = shaka.util.Dom.createHTMLElement('div'); diff --git a/ui/airplay_button.js b/ui/airplay_button.js index cefa8061b9..f34c755397 100644 --- a/ui/airplay_button.js +++ b/ui/airplay_button.js @@ -110,6 +110,7 @@ shaka.ui.AirPlayButton = class extends shaka.ui.Element { } /** + * @param {!AirPlayEvent} e * @private */ onAirPlayAvailabilityChange_(e) { diff --git a/ui/externs/ui.js b/ui/externs/ui.js index 0213685aef..22210e6c21 100644 --- a/ui/externs/ui.js +++ b/ui/externs/ui.js @@ -115,7 +115,7 @@ shaka.extern.UIVolumeBarColors; * The ordered list of ad statistics present in the ad statistics container. * @property {!Array.} playbackRates * The ordered list of rates for playback selection. - * @property {!Array.} fastForwardRates + * @property {!Array.} fastForwardRates * The ordered list of rates for fast forward selection. * @property {!Array.} rewindRates * The ordered list of rates for rewind selection. diff --git a/ui/gl_matrix/matrix_4x4.js b/ui/gl_matrix/matrix_4x4.js index 5561e7bf34..02eb9d8827 100644 --- a/ui/gl_matrix/matrix_4x4.js +++ b/ui/gl_matrix/matrix_4x4.js @@ -35,6 +35,7 @@ shaka.ui.Matrix4x4 = class { * @param {!Array.} eye Position of the viewer * @param {!Array.} center Point the viewer is looking at * @param {!Array.} up Vector pointing up + * @return {!Float32Array} */ static lookAt(out, eye, center, up) { let x0; @@ -166,6 +167,7 @@ shaka.ui.Matrix4x4 = class { * @param {number} aspect Aspect ratio. typically viewport width/height * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum, can be null or Infinity + * @return {!Float32Array} */ static perspective(out, fovy, aspect, near, far) { const f = 1.0 / Math.tan(fovy / 2); @@ -267,6 +269,7 @@ shaka.ui.Matrix4x4 = class { * @param {number} top Top bound of the frustum * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum + * @return {!Float32Array} */ static frustum(out, left, right, bottom, top, near, far) { const rl = 1 / (right - left); @@ -424,6 +427,7 @@ shaka.ui.Matrix4x4 = class { * same as the quaternion originally supplied. * @param {!Float32Array} out Quaternion to receive the rotation component * @param {!Float32Array} mat Matrix to be decomposed (input) + * @return {!Float32Array} */ static getRotation(out, mat) { const scaling = new Float32Array(3); @@ -526,12 +530,14 @@ shaka.ui.Matrix4x4 = class { * Set a 4x4 matrix to the identity matrix * * @param {!Float32Array} out the receiving matrix + * @return {!Float32Array} * @private */ static identity_(out) { for (let i = 0; i < 16; i++) { out[i] = (i % 5) == 0 ? 1 : 0; } + return out; } /** diff --git a/ui/presentation_time.js b/ui/presentation_time.js index 0f79799a01..9fa981eb03 100644 --- a/ui/presentation_time.js +++ b/ui/presentation_time.js @@ -64,7 +64,10 @@ shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element { }); } - /** @private */ + /** + * @param {string} value + * @private + */ setValue_(value) { // To avoid constant updates to the DOM, which makes debugging more // difficult, only set the value if it has changed. If we don't do this diff --git a/ui/seek_bar.js b/ui/seek_bar.js index 922c8a1507..8f034304ca 100644 --- a/ui/seek_bar.js +++ b/ui/seek_bar.js @@ -313,7 +313,7 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement { /** * @override - */ + */ isShowing() { // It is showing by default, so it is hidden if shaka-hidden is in the list. return !this.container.classList.contains('shaka-hidden'); diff --git a/ui/statistics_button.js b/ui/statistics_button.js index 6c94bde578..7fe086b3cd 100644 --- a/ui/statistics_button.js +++ b/ui/statistics_button.js @@ -220,7 +220,11 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element { this.stateSpan_.textContent = this.localization.resolve(labelText); } - /** @private */ + /** + * @param {string} name + * @return {!HTMLElement} + * @private + */ generateComponent_(name) { const section = shaka.util.Dom.createHTMLElement('div'); diff --git a/ui/vr_manager.js b/ui/vr_manager.js index 83b8399303..7861807f85 100644 --- a/ui/vr_manager.js +++ b/ui/vr_manager.js @@ -551,7 +551,7 @@ shaka.ui.VRManager = class extends shaka.util.FakeEventTarget { }; /** - * @constant {number} + * @const {number} * @private */ shaka.ui.VRManager.TO_RADIANS_ = Math.PI / 180; diff --git a/ui/vr_utils.js b/ui/vr_utils.js index 0dfbad3d5b..596c6a6484 100644 --- a/ui/vr_utils.js +++ b/ui/vr_utils.js @@ -162,7 +162,7 @@ shaka.ui.VRUtils = class { /** * Sphere vertex shader. * - * @constant {string} + * @const {string} */ shaka.ui.VRUtils.VERTEX_SPHERE_SHADER = `attribute vec4 a_vPosition; @@ -183,7 +183,7 @@ void main() /** * Sphere fragment shader. * - * @constant {string} + * @const {string} */ shaka.ui.VRUtils.FRAGMENT_SPHERE_SHADER = `precision highp float; @@ -204,7 +204,7 @@ highp vec4 texelColor = /** * Cube vertex shader. * - * @constant {string} + * @const {string} */ shaka.ui.VRUtils.VERTEX_CUBE_SHADER = `attribute vec4 aVertexPosition; @@ -221,7 +221,7 @@ void main(void) { /** * Cube fragment shader. * - * @constant {string} + * @const {string} */ shaka.ui.VRUtils.FRAGMENT_CUBE_SHADER = `varying highp vec2 vTextureCoord; diff --git a/ui/vr_webgl.js b/ui/vr_webgl.js index 64e1611f16..59c7a48338 100644 --- a/ui/vr_webgl.js +++ b/ui/vr_webgl.js @@ -694,6 +694,6 @@ shaka.ui.VRWebgl = class { }; /** - * @constant {number} + * @const {number} */ shaka.ui.VRWebgl.ANIMATION_DURATION_ = 0.5;