$ date
--- stdout ---
Mon Mar 31 08:49:45 UTC 2025
--- end ---
$ git clone file:///srv/git/mediawiki-services-cxserver.git repo --depth=1 -b master
--- stderr ---
Cloning into 'repo'...
--- stdout ---
--- end ---
$ git config user.name libraryupgrader
--- stdout ---
--- end ---
$ git config user.email tools.libraryupgrader@tools.wmflabs.org
--- stdout ---
--- end ---
$ git submodule update --init
--- stdout ---
--- end ---
$ grr init
--- stdout ---
Installed commit-msg hook.
--- end ---
$ git show-ref refs/heads/master
--- stdout ---
166bd682cbfa5b4dbb97b51ffd7b172785352f37 refs/heads/master
--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
"auditReportVersion": 2,
"vulnerabilities": {},
"metadata": {
"vulnerabilities": {
"info": 0,
"low": 0,
"moderate": 0,
"high": 0,
"critical": 0,
"total": 0
},
"dependencies": {
"prod": 281,
"dev": 528,
"optional": 52,
"peer": 1,
"peerOptional": 0,
"total": 860
}
}
}
--- end ---
Upgrading n:eslint-config-wikimedia from 0.28.2 -> 0.29.1
$ /usr/bin/npm install
--- stderr ---
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: 'cxserver@1.2.1',
npm WARN EBADENGINE required: { node: '>=20' },
npm WARN EBADENGINE current: { node: 'v18.19.0', npm: '9.2.0' }
npm WARN EBADENGINE }
npm WARN deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm WARN deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm WARN deprecated npmlog@6.0.2: This package is no longer supported.
npm WARN deprecated @humanwhocodes/config-array@0.13.0: Use @eslint/config-array instead
npm WARN deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm WARN deprecated abab@2.0.6: Use your platform's native atob() and btoa() methods instead
npm WARN deprecated are-we-there-yet@3.0.1: This package is no longer supported.
npm WARN deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm WARN deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
npm WARN deprecated domexception@4.0.0: Use your platform's native DOMException instead
npm WARN deprecated gauge@4.0.4: This package is no longer supported.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options.
--- stdout ---
added 860 packages, and audited 861 packages in 10s
158 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json
--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json
--- end ---
$ ./node_modules/.bin/eslint . --fix
--- stdout ---
/src/repo/app.js
46:1 warning The type 'Express' is undefined jsdoc/no-undefined-types
81:34 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
84:25 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
222:9 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
223:10 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/bin/adapt.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/linear-reduce.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/linearize.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/mt.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/segment.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/translate.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/lib/Config.js
42:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
64:38 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
69:6 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
70:6 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
97:29 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/lib/adaptation/TemplateParameterMapper.js
110:5 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
110:7 warning Expected no linebreak before this expression implicit-arrow-linebreak
113:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
/src/repo/lib/lineardoc/MwContextualizer.js
143:35 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
/src/repo/lib/logging.js
7:1 warning The type 'winston' is undefined jsdoc/no-undefined-types
/src/repo/lib/mt/Apertium.js
37:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/Elia.js
92:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/Google.js
94:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/LingoCloud.js
74:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/MinT.js
55:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/Yandex.js
82:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mw/MWPageLoader.js
19:33 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/lib/mw/MwApiRequest.js
60:26 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
106:26 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
193:10 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/swagger-ui.js
26:9 warning Found readFile from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/lib/translationunits/MWCategory.js
15:41 warning Unsafe Regular Expression security/detect-unsafe-regex
/src/repo/lib/translationunits/MWFile.js
44:51 warning Unsafe Regular Expression security/detect-unsafe-regex
/src/repo/lib/translationunits/MWImage.js
123:68 warning Unsafe Regular Expression security/detect-unsafe-regex
/src/repo/lib/util.js
132:23 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/scripts/SectionTitleAlignment/alignwithmt.js
214:26 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/scripts/template-mapping.js
108:7 warning Found existsSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
114:14 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/spec.yaml
195:1 warning This line has a length of 139. Maximum allowed is 100 max-len
246:1 warning This line has a length of 139. Maximum allowed is 100 max-len
468:1 warning This line has a length of 109. Maximum allowed is 100 max-len
493:1 warning This line has a length of 110. Maximum allowed is 100 max-len
499:1 warning This line has a length of 216. Maximum allowed is 100 max-len
540:1 warning This line has a length of 110. Maximum allowed is 100 max-len
547:1 warning This line has a length of 216. Maximum allowed is 100 max-len
589:1 warning This line has a length of 106. Maximum allowed is 100 max-len
606:1 warning This line has a length of 134. Maximum allowed is 100 max-len
/src/repo/test/adaptation/AdaptationTest.js
1:25 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/adaptation/SectionTest.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
31:20 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/adaptation/TemplateParameterMapper.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/app/app.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/app/spec.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
21:16 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
168:10 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
/src/repo/test/features/info/info.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/v1/page.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/v2/page.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/lineardoc/LinearDoc.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
24:22 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
25:24 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
26:26 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
70:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
86:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
134:27 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
204:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/mt/Apertium.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Elia.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Google.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/LingCloud.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/MTClient.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Template.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Yandex.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/transform.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mw/MWPageLoaderTest.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
37:27 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
46:5 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/mw/SectionWrap.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
17:33 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/segmentation/CXSegmenter.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
24:19 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
30:3 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/suggestions/SectionSuggestion.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/testutils.js
22:5 warning Found writeFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/translationunits/MWLink.test.js
1:25 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/translationunits/MWReference.test.js
1:25 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
38:21 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
53:27 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/utils/assert.js
7:40 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
✖ 90 problems (6 errors, 84 warnings)
--- end ---
$ ./node_modules/.bin/eslint . -f json
--- stdout ---
[{"filePath":"/src/repo/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/app.js","messages":[{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Express' is undefined.","line":46,"column":1,"nodeType":"Block","endLine":46,"endColumn":1},{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":81,"column":34,"nodeType":"NewExpression","endLine":81,"endColumn":138},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":84,"column":25,"nodeType":"CallExpression","endLine":84,"endColumn":58},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":222,"column":9,"nodeType":"CallExpression","endLine":222,"endColumn":45},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":223,"column":10,"nodeType":"CallExpression","endLine":223,"endColumn":46}],"suppressedMessages":[{"ruleId":"camelcase","severity":2,"message":"Identifier 'compression_level' is not in camel case.","line":31,"column":2,"nodeType":"Identifier","messageId":"notCamelCase","endLine":31,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'log_header_whitelist' is not in camel case.","line":35,"column":2,"nodeType":"Identifier","messageId":"notCamelCase","endLine":35,"endColumn":22,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'log_header_whitelist' is not in camel case.","line":81,"column":11,"nodeType":"Identifier","messageId":"notCamelCase","endLine":81,"endColumn":31,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * @external Application\n */\n\nimport { createServer as createHTTPServer } from 'http';\nimport { createServer as createHTTPSServer } from 'https';\nimport { readFileSync } from 'fs';\nimport { inspect } from 'util';\nimport { randomUUID } from 'crypto';\nimport express from 'express';\nimport compression from 'compression';\nimport { load } from 'js-yaml';\nimport bodyParser from 'body-parser';\nimport addShutdown from 'http-shutdown';\nimport { HTTPError, responseTimeMetricsMiddleware } from './lib/util.js';\nimport MTClientError from './lib/mt/MTClientError.js';\nimport packageInfo from './package.json' assert { type: 'json' };\nimport CXConfig from './lib/Config.js';\nimport PrometheusClient from './lib/metric.js';\nimport { logger } from './lib/logging.js';\nimport infoRoutes from './lib/routes/info.js';\nimport rootRoutes from './lib/routes/root.js';\nimport { router as v1Routes } from './lib/routes/v1.js';\nimport v2Routes from './lib/routes/v2.js';\n\nconst defaultConfig = {\n\tname: packageInfo.name,\n\tport: 8888,\n\tinterface: '0.0.0.0',\n\t// eslint-disable-next-line camelcase\n\tcompression_level: 3,\n\tcors: '*',\n\tcsp: 'default-src \\'self\\'; object-src \\'none\\'; media-src *; img-src *; style-src *; frame-ancestors \\'self\\'',\n\t// eslint-disable-next-line camelcase\n\tlog_header_whitelist: [\n\t\t'cache-control', 'content-type', 'content-length', 'if-match',\n\t\t'user-agent', 'x-request-id'\n\t],\n\tspecfile: './spec.yaml'\n};\n\n/**\n * Creates an express app and initialises it\n *\n * @param {Object} options the options to initialise the app with\n * @return {Express} the express app object\n */\nexport async function initApp( options ) {\n\tconst app = express();\n\n\toptions = Object.assign( {}, defaultConfig, options );\n\n\t// get the options and make them available in the app\n\tapp.logger = logger(\n\t\toptions.name,\n\t\toptions.logging\n\t);\n\tapp.logger.log( 'info', `Starting ${ options.name }` );\n\tapp.conf = options; // this app's config options\n\tapp.info = packageInfo; // this app's package info\n\tapp.metrics = new PrometheusClient( {\n\t\tcollectDefaultMetrics: true,\n\t\tstaticLabels: { service: options.name }\n\t} ); // the metrics\n\n\t// set outgoing proxy\n\tif ( app.conf.proxy ) {\n\t\tprocess.env.HTTP_PROXY = app.conf.proxy;\n\t\t// if there is a list of domains which should\n\t\t// not be proxied, set it\n\t\tif ( app.conf.no_proxy_list ) {\n\t\t\tif ( Array.isArray( app.conf.no_proxy_list ) ) {\n\t\t\t\tprocess.env.NO_PROXY = app.conf.no_proxy_list.join( ',' );\n\t\t\t} else {\n\t\t\t\tprocess.env.NO_PROXY = app.conf.no_proxy_list;\n\t\t\t}\n\t\t}\n\t}\n\n\t// eslint-disable-next-line camelcase\n\tapp.conf.log_header_whitelist = new RegExp( `^(?:${ app.conf.log_header_whitelist.map( ( item ) => item.trim() ).join( '|' ) })$`, 'i' );\n\n\ttry {\n\t\tapp.conf.spec = load( readFileSync( app.conf.specfile ) );\n\t} catch ( e ) {\n\t\tapp.logger.log( 'warn/spec', `Could not load the spec: ${ e }` );\n\t\tapp.conf.spec = {};\n\t}\n\n\t// set the CORS and CSP headers.\n\tapp.all( '*', ( req, res, next ) => {\n\t\tif ( app.conf.cors !== false ) {\n\t\t\tres.header( 'access-control-allow-origin', app.conf.cors );\n\t\t\tres.header( 'access-control-allow-headers', 'accept, authorization, x-requested-with, content-type, x-wikimedia-debug' );\n\t\t\tres.header( 'access-control-expose-headers', 'etag' );\n\t\t}\n\t\tif ( app.conf.csp !== false ) {\n\t\t\tres.header( 'x-xss-protection', '1; mode=block' );\n\t\t\tres.header( 'x-content-type-options', 'nosniff' );\n\t\t\tres.header( 'x-frame-options', 'SAMEORIGIN' );\n\t\t\tres.header( 'content-security-policy', app.conf.csp );\n\t\t\tres.header( 'x-content-security-policy', app.conf.csp );\n\t\t\tres.header( 'x-webkit-csp', app.conf.csp );\n\t\t}\n\n\t\tnext();\n\t} );\n\n\t// disable the X-Powered-By header\n\tapp.set( 'x-powered-by', false );\n\t// disable the ETag header.Yet to identify a valid need for cxserver.\n\tapp.set( 'etag', false );\n\t// enable compression\n\tapp.use( compression( {\n\t\tlevel: app.conf.compression_level\n\t} ) );\n\t// use the application/x-www-form-urlencoded parser\n\tapp.use( bodyParser.urlencoded( {\n\t\textended: true,\n\t\tlimit: 500000 // 0.5 megabyte\n\t} ) );\n\t// use the JSON body parser\n\tapp.use( bodyParser.json( {\n\t\tlimit: 500000\n\t} ) );\n\n\t// Add a middleware to log the response time\n\tapp.use( responseTimeMetricsMiddleware( app ) );\n\n\tapp.use( ( req, res, next ) => {\n\t\tapp.logger = app.logger.child( {\n\t\t\turl: {\n\t\t\t\tpath: req.url\n\t\t\t},\n\t\t\thttp: {\n\t\t\t\trequest: {\n\t\t\t\t\tmethod: req.method,\n\t\t\t\t\tid: randomUUID()\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t\tnext();\n\t} );\n\n\tapp.use( '/', rootRoutes );\n\tapp.use( '/v1', v1Routes );\n\tapp.use( '/v2', v2Routes );\n\tapp.use( '/_info', infoRoutes );\n\tapp.get( '/metrics', async ( req, res ) => {\n\t\tres.set( 'Content-Type', app.metrics.client.register.contentType );\n\t\tres.end( await app.metrics.metrics() );\n\t} );\n\n\t// Catch and handle propagated errors\n\tapp.use( ( err, req, res, next ) => {\n\t\tif ( err.cause ) {\n\t\t\t// ECS doesn't support a \"cause\" field in error\n\t\t\t// Log the error to a custom field.\n\t\t\t// See: https://www.elastic.co/guide/en/ecs/current/ecs-custom-fields-in-ecs.html\n\t\t\terr.Cause = inspect( err, { depth: 4 } );\n\t\t}\n\n\t\tif ( err instanceof HTTPError ) {\n\t\t\t// For HTTPError, only log errors with 500+ status codes\n\t\t\tif ( err.status >= 500 ) {\n\t\t\t\tapp.logger.error( 'HTTP Error details:', err );\n\t\t\t}\n\t\t} else if ( err instanceof MTClientError ) {\n\t\t\tif ( err.status >= 500 ) {\n\t\t\t\tapp.logger.error( 'MT Client Error', err );\n\t\t\t}\n\t\t} else {\n\t\t\tapp.logger.error( 'Error details:', err );\n\t\t}\n\n\t\tif ( res.writableFinished ) {\n\t\t\t// response has been sent and we've logged the error\n\t\t\t// Avoid passing the error to Express error handler to have\n\t\t\t// it be logged again by Express in a format that's not supported.\n\t\t\t// See: T377966\n\t\t\treturn;\n\t\t}\n\n\t\tif ( res.headersSent ) {\n\t\t\t// Headers have been sent, but the response has not been flushed out.\n\t\t\t// Send the error to Express to log and flush the response.\n\t\t\treturn next( err );\n\t\t}\n\n\t\tres.status( err.status || 500 );\n\n\t\tres.json( {\n\t\t\terror: {\n\t\t\t\tmessage: err.message || 'Internal Server Error',\n\t\t\t\tstatus: err.status\n\t\t\t}\n\t\t} );\n\n\t} );\n\n\tconst config = new CXConfig( app );\n\tawait config.parseAndLoadConfig();\n\tapp.registry = config;\n\n\treturn app;\n}\n\n/**\n * Creates and starts the service's web server\n *\n * @param {Application} app the app object to use in the service\n * @return {Promise} a promise creating the web server\n */\nfunction createServer( app ) {\n\t// return a promise which creates an HTTP or HTTPS server,\n\t// attaches the app to it, and starts accepting\n\t// incoming client requests\n\tlet server;\n\tconst isHttps = app.conf.private_key && app.conf.certificate;\n\tif ( isHttps ) {\n\t\tconst credentials = {\n\t\t\tkey: readFileSync( app.conf.private_key ),\n\t\t\tcert: readFileSync( app.conf.certificate )\n\t\t};\n\t\tserver = createHTTPSServer( credentials, app );\n\t} else {\n\t\tserver = createHTTPServer( app );\n\t}\n\n\treturn new Promise( ( resolve ) => {\n\t\tserver = server.listen( app.conf.port, app.conf.interface, resolve );\n\t\tserver = addShutdown( server );\n\t} ).then( () => {\n\t\tapp.logger.log( 'info',\n\t\t\t`Worker ${ process.pid } listening on http${ isHttps ? 's' : '' }://${ app.conf.interface || '*' }:${ app.conf.port }` );\n\t\treturn server;\n\t} );\n}\n\nexport default async function ( options ) {\n\tconst app = await initApp( options );\n\tcreateServer( app );\n\tprocess.on( 'unhandledRejection', ( reason /* promise */ ) => {\n\t\tapp.logger.error( 'Unhandled Promise Rejection', {\n\t\t\terror: reason,\n\t\t\tstack: reason.stack\n\t\t} );\n\t} );\n\treturn app;\n};\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/bin/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/bin/adapt.js","messages":[{"ruleId":"es-x/no-hashbang","severity":2,"message":"ES2023 Hashbang comments are forbidden.","line":1,"column":1,"nodeType":"Shebang","messageId":"forbidden","endLine":1,"endColumn":20}],"suppressedMessages":[{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":28,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":28,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"#!/usr/bin/env node\n\n/* eslint-disable n/no-process-exit */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../lib/logging.js';\nimport Adapter from '../lib/Adapter.js';\nimport PrometheusClient from '../lib/metric.js';\nimport MWApiRequestManager from '../lib/mw/MWApiRequestManager.js';\nimport TestClient from '../lib/mt/TestClient.js';\nimport { getConfig } from '../lib/util.js';\n\nconst cxConfig = getConfig();\ncxConfig.logger = logger(\n\tcxConfig.name,\n\tcxConfig.logging\n);\ncxConfig.metrics = new PrometheusClient( {\n\tstaticLabels: { service: 'cxserver' }\n} );\n\nconst xhtml = readFileSync( '/dev/stdin', 'utf8' );\nif ( xhtml.trim() === '' || process.argv.length !== 4 ) {\n\tconst script = process.argv[ 1 ];\n\tprocess.stderr.write(\n\t\t'Usage: node ' + script + ' fromLang toLang < file\\n'\n\t);\n\tprocess.exit( 1 );\n\n}\n\ncxConfig.mtClient = new TestClient( cxConfig );\n\nconst from = process.argv[ 2 ];\nconst to = process.argv[ 3 ];\nconst api = new MWApiRequestManager( cxConfig );\nconst adapter = new Adapter( from, to, api, cxConfig );\nadapter.adapt( xhtml ).then( ( result ) => {\n\tprocess.stdout.write( result.getHtml() + '\\n' );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/bin/linear-reduce.js","messages":[{"ruleId":"es-x/no-hashbang","severity":2,"message":"ES2023 Hashbang comments are forbidden.","line":1,"column":1,"nodeType":"Shebang","messageId":"forbidden","endLine":1,"endColumn":20}],"suppressedMessages":[{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":14,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":14,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"#!/usr/bin/env node\n\n/* eslint-disable n/no-process-exit */\n\nimport { readFileSync } from 'fs';\nimport * as LinearDoc from '../lib/lineardoc/index.js';\nconst html = readFileSync( '/dev/stdin', 'utf8' );\nif ( html.trim() === '' ) {\n\tconst script = process.argv[ 1 ];\n\tprocess.stderr.write(\n\t\t'Usage: node ' + script + ' < file\\n' +\n\t\t'Input must be wrapped in a block element such as <p>...</p> or <div>..</div>.\\n'\n\t);\n\tprocess.exit( 1 );\n\n}\n\nconst parser = new LinearDoc.Parser( new LinearDoc.MwContextualizer() );\nparser.init();\nparser.write( html );\nconst { reducedDoc, extractedData } = parser.builder.doc.reduce();\nprocess.stdout.write( reducedDoc.getHtml() );\nprocess.stdout.write( '\\n== Attributes ==\\n' );\nprocess.stdout.write( JSON.stringify( extractedData, null, 2 ) + '\\n' );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/bin/linearize.js","messages":[{"ruleId":"es-x/no-hashbang","severity":2,"message":"ES2023 Hashbang comments are forbidden.","line":1,"column":1,"nodeType":"Shebang","messageId":"forbidden","endLine":1,"endColumn":20}],"suppressedMessages":[{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":15,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":15,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"#!/usr/bin/env node\n\n/* eslint-disable n/no-process-exit */\n\nimport { readFileSync } from 'fs';\nimport { Parser, MwContextualizer } from '../lib/lineardoc/index.js';\n\nconst xhtml = readFileSync( '/dev/stdin', 'utf8' );\nif ( xhtml.trim() === '' ) {\n\tconst script = process.argv[ 1 ];\n\tprocess.stderr.write(\n\t\t'Usage: node ' + script + ' < file\\n' +\n\t\t'Input must be wrapped in a block element such as <p>...</p> or <div>..</div>.\\n'\n\t);\n\tprocess.exit( 1 );\n}\n\nconst parser = new Parser( new MwContextualizer() );\nparser.init();\nparser.write( xhtml );\nprocess.stdout.write( parser.builder.doc.dumpXml() );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/bin/mt.js","messages":[{"ruleId":"es-x/no-hashbang","severity":2,"message":"ES2023 Hashbang comments are forbidden.","line":1,"column":1,"nodeType":"Shebang","messageId":"forbidden","endLine":1,"endColumn":20}],"suppressedMessages":[{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":26,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":26,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":46,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":46,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":63,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":63,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"#!/usr/bin/env node\n\n/* eslint-disable n/no-process-exit */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../lib/logging.js';\nimport { getConfig } from '../lib/util.js';\nimport PrometheusClient from '../lib/metric.js';\nimport * as MTClients from '../lib/mt/index.js';\n\nconst cxConfig = getConfig();\ncxConfig.logger = logger(\n\tcxConfig.name,\n\tcxConfig.logging\n);\ncxConfig.metrics = new PrometheusClient( {\n\tstaticLabels: { service: 'cxserver' }\n} );\n\nfunction showHelpAndExit() {\n\tconst script = process.argv[ 1 ];\n\tprocess.stderr.write(\n\t\t'Usage: node ' + script + ' <sourceLang> <targetLang> < xhtmlSource\\n\\n' +\n\t\t'Example:\\n\\techo \"<p>A <b>red</b> box.</p>\" | node ' + script + ' Apertium en es\\n\\n'\n\t);\n\tprocess.exit( 1 );\n}\n\nconst args = process.argv.slice( 2 );\nif ( args.length !== 3 ) {\n\tshowHelpAndExit();\n}\n\nconst mtService = args[ 0 ];\nconst sourceLang = args[ 1 ];\nconst targetLang = args[ 2 ];\n\nconst sourceHtml = readFileSync( '/dev/stdin', 'utf8' );\n\nif ( sourceHtml.trim() === '' ) {\n\tshowHelpAndExit();\n}\n\nif ( !MTClients[ mtService ] ) {\n\tprocess.stderr.write( `Cannot find MT service: ${ mtService }` );\n\tprocess.exit( 1 );\n}\n\nconst mt = new MTClients[ mtService ]( cxConfig );\n\nmt.translateHtml(\n\tsourceLang,\n\ttargetLang,\n\tsourceHtml\n).then( ( targetHtml ) => {\n\tprocess.stdout.write( targetHtml + '\\n' );\n} ).catch( ( error ) => {\n\tif ( error.stack ) {\n\t\tprocess.stderr.write( error.stack );\n\t} else {\n\t\tprocess.stderr.write( error );\n\t}\n\tprocess.exit( 2 );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/bin/segment.js","messages":[{"ruleId":"es-x/no-hashbang","severity":2,"message":"ES2023 Hashbang comments are forbidden.","line":1,"column":1,"nodeType":"Shebang","messageId":"forbidden","endLine":1,"endColumn":20}],"suppressedMessages":[{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":36,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":36,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"#!/usr/bin/env node\n\n/* eslint-disable n/no-process-exit */\n\nimport { readFileSync } from 'fs';\nimport { load } from 'js-yaml';\nimport Segmenter from '../lib/segmentation/CXSegmenter.js';\nimport { Normalizer, Parser, MwContextualizer } from '../lib/lineardoc/index.js';\n\nfunction normalize( html ) {\n\tconst normalizer = new Normalizer();\n\tnormalizer.init();\n\tnormalizer.write( html.replace( /[\\t\\r\\n]+/g, '' ) );\n\treturn normalizer.getHtml();\n}\n\nfunction getParsedDoc( content ) {\n\tconst pageloaderConfig = load( readFileSync( __dirname + '/../config/MWPageLoader.yaml' ) );\n\tconst parser = new Parser( new MwContextualizer(\n\t\t{ removableSections: pageloaderConfig.removableSections }\n\t), {\n\t\twrapSections: true\n\t} );\n\tparser.init();\n\tparser.write( content );\n\treturn parser.builder.doc;\n}\n\nconst inputHtml = readFileSync( '/dev/stdin', 'utf8' );\nif ( inputHtml.trim() === '' ) {\n\tconst script = process.argv[ 1 ];\n\tprocess.stderr.write(\n\t\t'Usage: node ' + script + ' < file\\n' +\n\t\t'Input must be wrapped in a block element such as <p>...</p> or <div>..</div>.\\n'\n\t);\n\tprocess.exit( 1 );\n\n}\nconst language = process.argv[ 2 ];\nconst parsedDoc = getParsedDoc( inputHtml );\nconst segmenter = new Segmenter();\nconst segmentedLinearDoc = segmenter.segment( parsedDoc, language );\nconst result = normalize( segmentedLinearDoc.getHtml() );\nprocess.stdout.write( result + '\\n' );\nprocess.stdout.write( '==Categories==\\n' );\nprocess.stdout.write( JSON.stringify( parsedDoc.categories, null, 2 ) + '\\n' );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/bin/translate.js","messages":[{"ruleId":"es-x/no-hashbang","severity":2,"message":"ES2023 Hashbang comments are forbidden.","line":1,"column":1,"nodeType":"Shebang","messageId":"forbidden","endLine":1,"endColumn":20}],"suppressedMessages":[{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":29,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":29,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"n/no-process-exit","severity":1,"message":"Don't use process.exit(); throw an error instead.","line":39,"column":2,"nodeType":"CallExpression","messageId":"noProcessExit","endLine":39,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"#!/usr/bin/env node\n\n/* eslint-disable n/no-process-exit */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../lib/logging.js';\nimport { getConfig } from '../lib/util.js';\n\nimport Adapter from '../lib/Adapter.js';\nimport * as MTClients from '../lib/mt/index.js';\nimport MWApiRequestManager from '../lib/mw/MWApiRequestManager.js';\nimport PrometheusClient from '../lib/metric.js';\n\nconst cxConfig = getConfig();\ncxConfig.logger = logger(\n\tcxConfig.name,\n\tcxConfig.logging\n);\ncxConfig.metrics = new PrometheusClient( {\n\tstaticLabels: { service: 'cxserver' }\n} );\n\nconst sourceHtml = readFileSync( '/dev/stdin', 'utf8' );\nif ( sourceHtml.trim() === '' || process.argv.length !== 5 ) {\n\tconst script = process.argv[ 1 ];\n\tprocess.stderr.write(\n\t\t`Usage: node ${ script } Apertium fromLang toLang < file\\n`\n\t);\n\tprocess.exit( 1 );\n\n}\n\nconst mtService = process.argv[ 2 ];\nconst sourceLang = process.argv[ 3 ];\nconst targetLang = process.argv[ 4 ];\n\nif ( !MTClients[ mtService ] ) {\n\tprocess.stderr.write( `Cannot find MT service: ${ mtService }` );\n\tprocess.exit( 1 );\n}\n\nconst mt = new MTClients[ mtService ]( cxConfig );\ncxConfig.mtClient = mt;\n\nmt.translate(\n\tsourceLang,\n\ttargetLang,\n\tsourceHtml\n).then( ( targetHtml ) => {\n\tconst api = new MWApiRequestManager( cxConfig );\n\tconst adapter = new Adapter( sourceLang, targetLang, api, cxConfig );\n\tadapter.adapt( targetHtml ).then( ( result ) => {\n\t\tprocess.stdout.write( result.getHtml() + '\\n' );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/config.dev.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config.prod.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/Apertium.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/Elia.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/Google.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/JsonDict.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/LingoCloud.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/MWPageLoader.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/MinT.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/TestClient.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/Yandex.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/languages.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/mt-defaults.wikimedia.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/config/transform.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/docker-compose.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/eslint.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/jsduck.categories.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/jsduck.config.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/lib/Adapter.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/Config.js","messages":[{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":42,"column":28,"nodeType":"CallExpression","endLine":42,"endColumn":67},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":64,"column":38,"nodeType":"CallExpression","endLine":64,"endColumn":65},{"ruleId":"no-mixed-spaces-and-tabs","severity":1,"message":"Mixed spaces and tabs.","line":69,"column":6,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":69,"endColumn":8},{"ruleId":"no-mixed-spaces-and-tabs","severity":1,"message":"Mixed spaces and tabs.","line":70,"column":6,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":70,"endColumn":8},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":97,"column":29,"nodeType":"CallExpression","endLine":97,"endColumn":59}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { readFileSync } from 'fs';\nimport { load } from 'js-yaml';\n\nclass CXConfig {\n\tconstructor( app ) {\n\t\tthis.app = app;\n\t\tthis.logger = app.logger;\n\t\tthis.languages = null;\n\t\tthis.mt = {};\n\t}\n\n\tlog( level, info ) {\n\t\tif ( this.logger && this.logger.log ) {\n\t\t\tthis.logger.log( level, info );\n\t\t}\n\t}\n\n\tisObject( x ) {\n\t\treturn ( !!x ) && ( x.constructor === Object );\n\t}\n\n\tisString( x ) {\n\t\treturn typeof x === 'string' || x instanceof String;\n\t}\n\n\tasync parseAndLoadConfig() {\n\t\t// Supported languages\n\t\tthis.loadLanguageConf();\n\t\tthis.log( 'debug', `Found ${ this.languages?.length } languages from the configuration` );\n\t\t// Machine translation providers\n\t\tthis.mt = await this.loadServiceConf( this.app.conf.mt, 'mt' );\n\t\tthis.log( 'debug', `Found ${ Object.keys( this.mt ).length } MT providers` );\n\t}\n\n\tloadLanguageConf() {\n\t\tif ( Array.isArray( this.app.conf.languages ) ) {\n\t\t\t// Configuration is provided as an array\n\t\t\tthis.languages = this.app.conf.languages;\n\t\t} else if ( this.isString( this.app.conf.languages ) ) {\n\t\t\t// Configuration is provided in the named file\n\t\t\ttry {\n\t\t\t\tthis.languages = load( readFileSync( this.app.conf.languages ) );\n\t\t\t} catch ( e ) {\n\t\t\t\tthis.log( 'warn/spec', 'Could not load the languages registry: ' + e );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.log( 'error', 'Could not parse cxserver.conf.languages' );\n\t\t}\n\t}\n\n\tasync loadServiceConf( input, type ) {\n\t\tconst output = {};\n\t\tconst providers = Object.keys( input ).filter( ( item ) => item !== 'defaults' );\n\n\t\tfor ( const providerName of providers ) {\n\t\t\tconst languageRef = input[ providerName ].languages;\n\n\t\t\tif ( this.isObject( languageRef ) ) {\n\t\t\t\t// Language configuration is provided as an object\n\t\t\t\toutput[ providerName ] = languageRef;\n\t\t\t} else if ( this.isString( languageRef ) ) {\n\t\t\t\t// Language configuration is provided in the named file\n\t\t\t\ttry {\n\t\t\t\t\tconst providerLanguages = load( readFileSync( languageRef ) );\n\n\t\t\t\t\t// Allow hooking in JavaScript code to define the language pairs\n\t\t\t\t\tif ( providerLanguages.handler ) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t const Handler = ( await import( '../config/' + providerLanguages.handler ) ).default;\n\t\t\t\t\t\t output[ providerName ] = new Handler( providerLanguages ).languages;\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\tthis.log( 'error', `Could not load handler '${ providerLanguages.handler }': ${ e }` );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutput[ providerName ] = providerLanguages;\n\t\t\t\t\t}\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\tthis.log( 'error', `Could not load or parse file '${ languageRef }': ${ e }` );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.log( 'error', `Could not parse cxserver.conf.${ type }.${ providerName }` );\n\t\t\t}\n\t\t}\n\n\t\t// Handle \"default provider\" configuration separately\n\t\tif ( !input.defaults ) {\n\t\t\treturn output;\n\t\t}\n\n\t\tif ( Array.isArray( input.defaults ) ) {\n\t\t\t// \"Default provider\" configuration is provided as an array\n\t\t\toutput.defaults = input.defaults;\n\t\t} else if ( this.isString( input.defaults ) ) {\n\t\t\t// \"Default provider\" configuration is provided in the named file\n\t\t\ttry {\n\t\t\t\toutput.defaults = load( readFileSync( input.defaults ) );\n\t\t\t} catch ( e ) {\n\t\t\t\tthis.log( 'error', `Could not load or parse file '${ input.defaults }': ${ e }` );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.log( 'error', `Could not parse cxserver.conf.${ type }.defaults` );\n\t\t}\n\n\t\treturn output;\n\t}\n\n\t/**\n\t * Return all language pairs.\n\t *\n\t * @return {Object} The languages, indexed by source language\n\t * pointing to a list of target languages.\n\t */\n\tget LanguagePairs() {\n\t\treturn {\n\t\t\tsource: this.languages,\n\t\t\ttarget: this.languages\n\t\t};\n\t}\n\n\tget MTPairs() {\n\t\treturn this.mt;\n\t}\n\n\t/**\n\t * Get the available toolset for the given language\n\t *\n\t * @param {string} language\n\t * @return {Object} The toolset for the given language\n\t */\n\tgetToolSetForLanguage( language ) {\n\t\tconst tools = { mt: this.mt },\n\t\t\tresult = { mt: {} };\n\n\t\tObject.keys( tools ).forEach( ( toolName ) => {\n\t\t\tconst tool = tools[ toolName ], providers = Object.keys( tool );\n\n\t\t\t// Go through default MTs for language pairs and filter out the pairs where\n\t\t\t// source language is equal to the language provided as param of this method.\n\t\t\t// Then, add target language and default MT to the result object.\n\t\t\tObject.keys( tool.defaults || {} )\n\t\t\t\t.filter( ( pair ) => pair.indexOf( language + '-' ) === 0 )\n\t\t\t\t.forEach( ( pair ) => {\n\t\t\t\t\tconst targetLanguage = pair.slice( language.length + 1 );\n\n\t\t\t\t\tresult[ toolName ][ targetLanguage ] =\n\t\t\t\t\t\tresult[ toolName ][ targetLanguage ] || [];\n\t\t\t\t\tresult[ toolName ][ targetLanguage ].push( tool.defaults[ pair ] );\n\t\t\t\t} );\n\n\t\t\tfor ( let i = 0, length = providers.length; i < length; i++ ) {\n\t\t\t\tconst provider = providers[ i ], languages = tool[ provider ][ language ];\n\n\t\t\t\tif ( !languages ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Add each target language to the result object as key\n\t\t\t\t// and push MT provider to the values array.\n\t\t\t\tfor ( let j = 0, langsLength = languages.length; j < langsLength; j++ ) {\n\t\t\t\t\tconst targetLanguage = languages[ j ],\n\t\t\t\t\t\tresults = result[ toolName ][ targetLanguage ];\n\n\t\t\t\t\tif ( !results ) {\n\t\t\t\t\t\tresult[ toolName ][ targetLanguage ] = [ provider ];\n\t\t\t\t\t} else if ( !results.includes( provider ) ) { // Don't duplicate providers\n\t\t\t\t\t\tresult[ toolName ][ targetLanguage ].push( provider );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get the available toolset for the given language pair\n\t *\n\t * @param {string} from source language\n\t * @param {string} to target language\n\t * @return {Object} the toolset (empty object if nothing available)\n\t */\n\tgetToolSet( from, to ) {\n\t\tconst result = {};\n\n\t\tif ( !to ) {\n\t\t\treturn this.getToolSetForLanguage( from );\n\t\t}\n\n\t\t// Known tools\n\t\tconst tools = { mt: this.mt };\n\n\t\tObject.keys( tools ).forEach( ( toolname ) => {\n\t\t\tlet defaultProvider;\n\t\t\tconst tool = tools[ toolname ];\n\t\t\tconst providers = Object.keys( tool );\n\t\t\t// If there is a default provider, add it to the beginning of array.\n\t\t\tif ( tool.defaults && tool.defaults[ from + '-' + to ] ) {\n\t\t\t\tdefaultProvider = tool.defaults[ from + '-' + to ];\n\t\t\t\tresult[ toolname ] = [ defaultProvider ];\n\t\t\t}\n\t\t\tfor ( let j = 0; j < providers.length; j++ ) {\n\t\t\t\tconst provider = tool[ providers[ j ] ];\n\t\t\t\tif ( provider[ from ] && provider[ from ].includes( to ) &&\n\t\t\t\t\tdefaultProvider !== providers[ j ]\n\t\t\t\t) {\n\t\t\t\t\tresult[ toolname ] = result[ toolname ] || [];\n\t\t\t\t\tresult[ toolname ].push( providers[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get the valid toolsets for the given language pair.\n\t * If the provider name is given, it is validated.\n\t * If provider name is not given, the first one that appears in the registry will be returned.\n\t * If not valid provider is found, the returns null.\n\t *\n\t * @param {string} from source language\n\t * @param {string} to target language\n\t * @param {string} serviceType Service type from the registry, such as 'mt' or 'dictionary'\n\t * @param {string} [providerName] If given, the provider is validated.\n\t * @return {string|null|boolean} Provider name\n\t */\n\tgetValidProvider( from, to, serviceType, providerName ) {\n\t\tconst toolset = this.getToolSet( from, to );\n\n\t\tif ( !toolset[ serviceType ] ) {\n\t\t\t// No tools found for this service for this language pair\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( providerName ) {\n\t\t\tif ( !toolset[ serviceType ].includes( providerName ) ) {\n\t\t\t\t// The requested provider doesn't appear in the registry,\n\t\t\t\t// so it's invalid\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// The provider is valid\n\t\t\treturn providerName;\n\t\t}\n\n\t\t// If provider not given, use the first one in the registry\n\t\treturn toolset[ serviceType ][ 0 ];\n\t}\n}\n\nexport default CXConfig;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/adaptation/TemplateParameterMapper.js","messages":[{"ruleId":"no-mixed-spaces-and-tabs","severity":1,"message":"Mixed spaces and tabs.","line":110,"column":5,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":110,"endColumn":7},{"ruleId":"implicit-arrow-linebreak","severity":1,"message":"Expected no linebreak before this expression.","line":110,"column":7,"nodeType":"Identifier","messageId":"unexpected","endLine":110,"endColumn":26},{"ruleId":"no-mixed-spaces-and-tabs","severity":1,"message":"Mixed spaces and tabs.","line":113,"column":4,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":113,"endColumn":6}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getProp } from '../util.js';\n\nclass TemplateParameterMapper {\n\tconstructor( sourceParams, sourceTemplateData, targetTemplateData, mappingFromDatabase = {} ) {\n\t\tthis.sourceParams = sourceParams;\n\t\tthis.sourceTemplateData = sourceTemplateData;\n\t\tthis.targetTemplateData = targetTemplateData;\n\t\tthis.parameterMap = {};\n\t\tthis.parametersAreMapped = false;\n\t\tthis.mappingFromDatabase = mappingFromDatabase;\n\t}\n\n\tgetAdaptedParameters() {\n\t\tconst adaptedParameters = {};\n\t\tconst parameterMap = this.getParameterMap();\n\t\tfor ( const name in this.sourceParams ) {\n\t\t\tif ( name in parameterMap ) {\n\t\t\t\tadaptedParameters[ parameterMap[ name ] ] = this.sourceParams[ name ];\n\t\t\t}\n\t\t}\n\n\t\treturn adaptedParameters;\n\t}\n\n\tgetMandatoryParamsForTarget() {\n\t\tif ( !this.targetTemplateData.params ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Object.keys( this.targetTemplateData.params ).filter(\n\t\t\t( paramName ) => this.targetTemplateData.params[ paramName ].required === true\n\t\t);\n\t}\n\n\tgetOptionalParamsForTarget() {\n\t\tif ( !this.targetTemplateData.params ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Object.keys( this.targetTemplateData.params ).filter(\n\t\t\t( paramName ) => this.targetTemplateData.params[ paramName ].required === false\n\t\t);\n\t}\n\n\t/**\n\t * Find target template parameter mapping for all the parameters in source template.\n\t *\n\t * @return {Object} Object with mapping from each source param to param name in target template.\n\t */\n\tgetParameterMap() {\n\t\tif ( this.parametersAreMapped ) {\n\t\t\treturn this.parameterMap;\n\t\t}\n\n\t\tconst sourceCitoidMap = getProp( [ 'maps', 'citoid' ], this.sourceTemplateData ) || {};\n\t\tconst targetCitoidMap = getProp( [ 'maps', 'citoid' ], this.targetTemplateData ) || {};\n\n\t\tfor ( const name in this.sourceParams ) {\n\t\t\tif ( !isNaN( name ) ) {\n\t\t\t\t// Unnamed parameters, which are named 1, 2, 3...\n\t\t\t\tthis.parameterMap[ name ] = name;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !this.targetTemplateData.params ) {\n\t\t\t\t// No params in target template data definition\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Try to locate this source param in the source template data definition\n\t\t\tconst normalizedKey = name.trim().toLowerCase().replace( /[\\s+_-]+/g, '' );\n\t\t\tconst sourceTemplateParam = this.sourceTemplateData.params[ name ] ||\n\t\t\t\tthis.sourceTemplateData.params[ normalizedKey ];\n\t\t\tlet sourceAliases = sourceTemplateParam ? sourceTemplateParam.aliases : [];\n\n\t\t\tif ( !sourceTemplateParam ) {\n\t\t\t\t// The source param name can be in the aliases of other params in source\n\t\t\t\t// template data. If so find that param and add aliases to sourceAliases\n\t\t\t\tconst paramMatchingAlias = Object.keys( this.sourceTemplateData.params ).find(\n\t\t\t\t\t( key ) => ( this.sourceTemplateData.params[ key ].aliases || [] )\n\t\t\t\t\t\t.includes( name )\n\t\t\t\t);\n\t\t\t\tif ( paramMatchingAlias ) {\n\t\t\t\t\tsourceAliases.push( paramMatchingAlias );\n\t\t\t\t\tsourceAliases = sourceAliases.concat(\n\t\t\t\t\t\tthis.sourceTemplateData.params[ paramMatchingAlias ].aliases || []\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst sourceKeyAndAliases = new Set( sourceAliases );\n\t\t\tsourceKeyAndAliases.add( name );\n\t\t\tsourceKeyAndAliases.add( normalizedKey );\n\n\t\t\t// Search in the aliases for a match - case insensitive.\n\t\t\tfor ( const paramName in this.targetTemplateData.params ) {\n\t\t\t\tconst param = this.targetTemplateData.params[ paramName ];\n\n\t\t\t\tconst targetKeyAndAliases = new Set(\n\t\t\t\t\t[\n\t\t\t\t\t\t...( param.aliases || [] ),\n\t\t\t\t\t\tparamName,\n\t\t\t\t\t\t// The citoid map inside the template data has parameter name mapping.\n\t\t\t\t\t\t// consider each of those mapping as an alias to target params.\n\t\t\t\t\t\t...this.getNameAliasesFromCitoid( paramName, sourceCitoidMap ),\n\t\t\t\t\t\t...this.getNameAliasesFromCitoid( paramName, targetCitoidMap )\n\t\t\t\t\t]\n\t\t\t\t);\n\n\t\t\t\t// Find intersection of sourceKeyAndAliases and targetKeyAndAliases\n\t\t\t\tconst match = ( [ ...targetKeyAndAliases ].some( ( key ) =>\n\t\t\t\t\t// key can be integer or string.\n\t\t\t\t\t sourceKeyAndAliases.has(\n\t\t\t\t\t\t`${ key }`.trim().toLowerCase().replace( /[\\s+_-]+/g, '' )\n\t\t\t\t\t)\n\t\t\t\t ) );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\t// Found a match\n\t\t\t\t\tthis.parameterMap[ name ] = paramName;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Still not found? Try templatemapping database\n\t\t\tif ( !this.parameterMap[ name ] && this.mappingFromDatabase[ name ] ) {\n\t\t\t\tthis.parameterMap[ name ] = this.mappingFromDatabase[ name ];\n\t\t\t}\n\t\t}\n\n\t\tthis.parametersAreMapped = true;\n\t\treturn this.parameterMap;\n\t}\n\n\t/**\n\t * For the given parameter name, get the aliases from the citoid map\n\t *\n\t * @param {string} paramName\n\t * @param {Object} citoidMap\n\t * @return {Set}\n\t */\n\tgetNameAliasesFromCitoid( paramName, citoidMap ) {\n\t\tconst aliases = new Set();\n\t\tconst citoidAliases = citoidMap[ paramName ];\n\t\tif ( !citoidAliases ) {\n\t\t\treturn aliases;\n\t\t}\n\t\tif ( !Array.isArray( citoidAliases ) ) {\n\t\t\taliases.add( citoidAliases );\n\t\t} else {\n\t\t\t// Sometimes citoid map values are nested arrays like\n\t\t\t// \"author\": [ [ \"first\", \"last\" ], [ \"first2\", \"last2\" ] ]\n\t\t\t// That is not a useful information to do parameter mapping.\n\t\t\tcitoidAliases\n\t\t\t\t.filter( ( alias ) => !Array.isArray( alias ) )\n\t\t\t\t.forEach( ( alias ) => aliases.add( alias ) );\n\t\t}\n\t\treturn aliases;\n\t}\n}\n\nexport default TemplateParameterMapper;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/adaptation/TemplateTransclusion.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/adaptation/TransclusionAdapter.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/adaptation/TransclusionFactory.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/adaptation/UnsupportedTransclusion.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/index.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/language-domain-mapping.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/Builder.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/Contextualizer.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/Doc.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/MwContextualizer.js","messages":[{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":143,"column":35,"nodeType":"NewExpression","endLine":143,"endColumn":90}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import Contextualizer from './Contextualizer.js';\nimport { getProp } from './../util.js';\nconst contentBranchNodeNames = [ 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre', 'div', 'table', 'ol', 'ul', 'dl', 'figure', 'center', 'section' ];\n\n/**\n * Contextualizer for MediaWiki DOM HTML\n *\n * See https://www.mediawiki.org/wiki/Specs/HTML\n *\n * @class\n * @extends Contextualizer\n * @constructor\n */\nclass MwContextualizer extends Contextualizer {\n\t/**\n\t * @param {Object} config\n\t * @param {Object} config.removableSections containing array of classes and rdfa values.\n\t * Tags matching these classes or rdfa values will be marked as removable.\n\t * See config/MWPageLoader.yaml\n\t */\n\tconstructor( config ) {\n\t\tsuper( config );\n\t\t// Array holding transclusion fragment ids(about attribute values)\n\t\tthis.removableTransclusionFragments = [];\n\t}\n\n\t/**\n\t * @inheritdoc\n\t */\n\tgetChildContext( tag ) {\n\t\tconst context = this.getContext(),\n\t\t\ttype = tag.attributes.typeof || tag.attributes.rel || '';\n\n\t\tif ( context === 'removable' || this.isRemovable( tag ) ) {\n\t\t\treturn 'removable';\n\t\t}\n\n\t\t// Any descendent of Transclusion/Placeholder is verbatim\n\t\tif ( context === 'verbatim' || type.match( /(^|\\s)(mw:Transclusion|mw:Placeholder)\\b/ ) ) {\n\t\t\treturn 'verbatim';\n\t\t}\n\n\t\t// Otherwise, figure is media\n\t\tif ( tag.name === 'figure' ) {\n\t\t\treturn 'media';\n\t\t}\n\n\t\tif ( tag.name === 'span' && type.match( /(^|\\s)(mw:File|mw:Image|mw:Video|mw:Audio)\\b/ ) ) {\n\t\t\treturn 'media-inline';\n\t\t}\n\n\t\t// Immediate childrens of body are sections\n\t\tif ( context === undefined && tag.name === 'body' ) {\n\t\t\treturn 'section';\n\t\t}\n\n\t\t// And figure//figcaption is contentBranch\n\t\tif ( ( context === 'media' || context === 'media-inline' ) && tag.name === 'figcaption' ) {\n\t\t\treturn 'contentBranch';\n\t\t}\n\n\t\t// And ContentBranchNodes are contentBranch\n\t\tif ( ( context === 'section' || context === undefined ) && contentBranchNodeNames.includes( tag.name ) ) {\n\t\t\treturn 'contentBranch';\n\t\t}\n\n\t\t// Else same as parent context\n\t\treturn context;\n\t}\n\n\t/**\n\t * @inheritdoc\n\t */\n\tcanSegment() {\n\t\treturn this.getContext() === 'contentBranch';\n\t}\n\n\t/**\n\t * Check if the tag need to be ignored while parsing and hence removed.\n\t *\n\t * @param {Object} tag\n\t * @return {boolean}\n\t */\n\tisRemovable( tag ) {\n\t\tconst removableSections = this.config.removableSections;\n\t\tif ( !this.config.removableSections ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.removableTransclusionFragments.includes( tag.attributes.about ) ) {\n\t\t\t// Once a transclusion is removed, make sure their fragments also removed\n\t\t\t// even if the fragment does not match with removableSections configuration.\n\t\t\treturn true;\n\t\t}\n\n\t\tconst classList = tag.attributes.class ? tag.attributes.class.split( ' ' ) : [];\n\t\tfor ( let i = 0; i < removableSections.classes.length; i++ ) {\n\t\t\tif ( classList.includes( removableSections.classes[ i ] ) ) {\n\t\t\t\tif ( tag.attributes.about ) {\n\t\t\t\t\tthis.removableTransclusionFragments.push( tag.attributes.about );\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tconst types = tag.attributes.typeof ? tag.attributes.typeof.split( ' ' ) : [];\n\t\tconst rels = tag.attributes.rel ? tag.attributes.rel.split( ' ' ) : [];\n\t\tconst rdfa = types.concat( rels );\n\t\tfor ( let i = 0; i < removableSections.rdfa.length; i++ ) {\n\t\t\t// Make sure that the rdfa value matches with removable section rdfa and does not\n\t\t\t// have other rdfas in same element.\n\t\t\tif ( rdfa.includes( removableSections.rdfa[ i ] && rdfa.length === 1 ) ) {\n\t\t\t\tif ( tag.attributes.about ) {\n\t\t\t\t\tthis.removableTransclusionFragments.push( tag.attributes.about );\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tconst dataMW = tag.attributes[ 'data-mw' ];\n\t\tif ( !dataMW ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// See https://phabricator.wikimedia.org/T274133 for more info\n\t\tlet mwData = {};\n\t\ttry {\n\t\t\tmwData = JSON.parse( dataMW );\n\t\t} catch ( e ) {\n\t\t\treturn false;\n\t\t}\n\t\tconst templateName = getProp( [ 'parts', 0, 'template', 'target', 'wt' ], mwData );\n\t\tif ( !templateName ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( let i = 0; i < removableSections.templates.length; i++ ) {\n\t\t\tlet removableTemplateNameRegExp;\n\t\t\tconst removableTemplateName = removableSections.templates[ i ];\n\n\t\t\tif ( removableTemplateName[ 0 ] === '/' && removableTemplateName.slice( -1 ) === '/' ) {\n\t\t\t\t// A regular expression is given.\n\t\t\t\tremovableTemplateNameRegExp = new RegExp( removableTemplateName.slice( 1, -1 ), 'i' );\n\t\t\t}\n\n\t\t\tconst match = removableTemplateNameRegExp ?\n\t\t\t\ttemplateName.match( removableTemplateNameRegExp ) :\n\t\t\t\ttemplateName.toLowerCase() === removableTemplateName.toLowerCase();\n\n\t\t\tif ( match ) {\n\t\t\t\tif ( tag.attributes.about ) {\n\t\t\t\t\tthis.removableTransclusionFragments.push( tag.attributes.about );\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\nexport default MwContextualizer;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/Normalizer.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/Parser.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/TextBlock.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/TextChunk.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/Utils.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/lineardoc/index.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/logging.js","messages":[{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'winston' is undefined.","line":7,"column":1,"nodeType":"Block","endLine":7,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { createLogger, format as logFormat, transports as logTransports } from 'winston';\nimport { ecsFormat } from '@elastic/ecs-winston-format';\n\n/**\n * @param {string} serviceName Name of the service. Added to default metadata of the logger.\n * @param {Object} options WinstonLoggerOptions, not to be confused with winston.LoggerOptions\n * @return {winston.Logger}\n */\nconst createWinstonLogger = ( serviceName, options = {} ) => {\n\t// Uses spread operator to fill options\n\t// with defaults first and then override with config\n\toptions = {\n\t\t...{\n\t\t\tlevel: 'info',\n\t\t\tstacktrace: true,\n\t\t\tformat: 'json',\n\t\t\ttransports: [ { transport: 'Console' } ]\n\t\t},\n\t\t...options\n\t};\n\n\treturn createLogger( {\n\t\tlevel: options.level,\n\t\tformat: logFormat.combine(\n\t\t\t// Enable stacktrace for errors\n\t\t\tlogFormat.errors( { stack: options.stacktrace } ),\n\t\t\toptions.format === 'ecs' ?\n\t\t\t\tecsFormat( options.formatOptions ) :\n\t\t\t\tlogFormat[ options.format || 'json' ](\n\t\t\t\t\toptions.format ? options.formatOptions : undefined\n\t\t\t\t)\n\t\t),\n\t\tdefaultMeta: {\n\t\t\tservice: serviceName\n\t\t},\n\t\ttransports: ( options.transports || [] ).map(\n\t\t\t( { transport, options: transportOptions } ) => new logTransports[ transport ]( {\n\t\t\t\t...transportOptions,\n\t\t\t\t// Spread format separately so we can add on options as parameters\n\t\t\t\t...( transportOptions && transportOptions.format ?\n\t\t\t\t\t{\n\t\t\t\t\t\tformat: logFormat.combine(\n\t\t\t\t\t\t\tlogFormat.errors( { stack: options.stacktrace } ),\n\t\t\t\t\t\t\ttransportOptions.format === 'ecs' ?\n\t\t\t\t\t\t\t\tecsFormat( transportOptions.formatOptions ) :\n\t\t\t\t\t\t\t\tlogFormat[ transportOptions.format ](\n\t\t\t\t\t\t\t\t\ttransportOptions.formatOptions\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t} :\n\t\t\t\t\t{} )\n\t\t\t} )\n\t\t)\n\t} );\n};\n\nexport const logger = createWinstonLogger;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/metric.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/Apertium.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":37,"column":27,"nodeType":"Identifier","messageId":"not-supported-till","endLine":37,"endColumn":32}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Agent } from 'undici';\nimport MTClient from './MTClient.js';\nimport apertiumLangMapping from './Apertium.languagenames.json' assert { type: 'json' };\n\nclass Apertium extends MTClient {\n\t/**\n\t * Translate plain text with Apertium API\n\t * Apertium is not capable of HTML translation with all annotation\n\t * mapping. For translating HTML, It uses CX's annotation mapping on top\n\t * of the plaintext translation. Hence it inherits translateHTML method\n\t * of MTClient.\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} sourceText Source language text\n\t * @return {Promise} promise: Target language text\n\t */\n\tasync translateText( sourceLang, targetLang, sourceText ) {\n\t\tconst url = this.conf.mt.Apertium.api + '/translate';\n\t\tconst headers = {\n\t\t\t'Content-Type': 'application/x-www-form-urlencoded'\n\t\t};\n\t\tconst body = {\n\t\t\tmarkUnknown: 0,\n\t\t\tlangpair: `${ apertiumLangMapping[ sourceLang ] }|${ apertiumLangMapping[ targetLang ] }`,\n\t\t\tformat: 'txt',\n\t\t\tq: sourceText\n\t\t};\n\t\tconst options = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: headers,\n\t\t\tbody: new URLSearchParams( body ),\n\t\t\tdispatcher: new Agent( { connect: { timeout: 60_000 } } )\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await fetch( url, options );\n\t\t\tif ( !response.ok ) {\n\t\t\t\tconst responseText = await response.text();\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Network error: HTTP ${ response.status } (${ response.statusText }): ${ responseText }`\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst data = await response.json();\n\t\t\tthis.metrics.makeMetric( {\n\t\t\t\ttype: 'Counter',\n\t\t\t\tname: 'translate.Apertium.charcount',\n\t\t\t\thelp: 'Apertium character count'\n\t\t\t} ).increment( sourceText.length );\n\t\t\tif ( data?.responseData?.translatedText !== null ) {\n\t\t\t\treturn data.responseData.translatedText;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Processing error. JSON missing responseData.translatedText: ' + JSON.stringify( data )\n\t\t\t\t);\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\tthrow new Error( `Translation with Apertium ${ sourceLang } > ${ targetLang } failed: ${ error.message }` );\n\t\t}\n\t}\n}\n\nexport default Apertium;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/Apertium.languagenames.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/Elia.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":92,"column":27,"nodeType":"Identifier","messageId":"not-supported-till","endLine":92,"endColumn":32}],"suppressedMessages":[{"ruleId":"camelcase","severity":2,"message":"Identifier 'api_id' is not in camel case.","line":69,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":69,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'api_key' is not in camel case.","line":70,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":70,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'translation_engine' is not in camel case.","line":71,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":71,"endColumn":22,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'content_type' is not in camel case.","line":72,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":72,"endColumn":16,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'language_pair' is not in camel case.","line":73,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":73,"endColumn":17,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { ProxyAgent } from 'undici';\nimport { HTTPError } from '../util.js';\nimport MTClient from './MTClient.js';\n\n/**\n * Elia machine translation service client.\n * API doc: https://mt-api.elhuyar.eus/\n * Source code: https://github.com/Elia\n * Note: Elia has multiple machine translation engines. \"nmt\" and \"apertium\"\n * Here we are using only \"nmt\" since we have Apertium MT service separately.\n * List of language pairs and MT engines can be obtained by using the API\n * https://mt-api.elhuyar.eus/language_pairs with API ID and Key params.\n */\n\nconst eliaLanguageNameMap = {\n\tsimple: 'en'\n};\n\nclass Elia extends MTClient {\n\t/**\n\t * @inheritdoc\n\t */\n\ttranslateLines( sourceLang, targetLang, sourceLines ) {\n\t\t// Join lines into single string. Separator must break sentences and pass through unchanged\n\t\tconst sourceLinesText = sourceLines.join( '\\n\\n' );\n\n\t\treturn this.translateText(\n\t\t\tsourceLang,\n\t\t\ttargetLang,\n\t\t\tsourceLinesText\n\t\t).then( ( targetLinesText ) => targetLinesText.split( /\\n\\n/g ) );\n\t}\n\n\t/**\n\t * Translate content with Elia API\n\t * Elia supports HTML translation, but the precision of inline tags is\n\t * not perfect to depend on it.\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} sourceText Source language content\n\t * @return {Promise} Target language content\n\t */\n\tasync translateText( sourceLang, targetLang, sourceText ) {\n\t\tconst key = this.conf.mt.Elia.key;\n\t\tconst apiId = this.conf.mt.Elia.apiId;\n\t\tif ( !key || !apiId ) {\n\t\t\tthrow new Error( 'Elia service is misconfigured' );\n\t\t}\n\t\t// Elia does not set limit on input content as per documentation, but here we set a limit\n\t\tconst length = sourceText.length;\n\t\tconst limit = 10000;\n\t\tif ( length > limit ) {\n\t\t\tthrow new HTTPError( {\n\t\t\t\tstatus: 413,\n\t\t\t\ttype: 'mt_error',\n\t\t\t\tdetail: `Elia: Source content too long: ${ length } (${ limit } is the limit)`\n\t\t\t} );\n\t\t}\n\n\t\tsourceLang = eliaLanguageNameMap[ sourceLang ] || sourceLang;\n\t\ttargetLang = eliaLanguageNameMap[ targetLang ] || targetLang;\n\t\tconst url = this.conf.mt.Elia.api;\n\t\tconst headers = {\n\t\t\t'Content-Type': 'application/json'\n\t\t};\n\t\t/* eslint-disable camelcase */\n\t\tconst body = {\n\t\t\tapi_id: apiId,\n\t\t\tapi_key: key,\n\t\t\ttranslation_engine: 'nmt',\n\t\t\tcontent_type: 'txt',\n\t\t\tlanguage_pair: `${ sourceLang }-${ targetLang }`,\n\t\t\ttext: sourceText\n\t\t};\n\t\tconst options = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: headers,\n\t\t\tbody: JSON.stringify( body )\n\t\t};\n\n\t\tif ( this.conf.proxy ) {\n\t\t\toptions.dispatcher = new ProxyAgent( this.conf.proxy, {\n\t\t\t\trequestTls: {\n\t\t\t\t\t// Ignore proxy certificate errors, if any.\n\t\t\t\t\trejectUnauthorized: false\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch( url, options );\n\t\t\tif ( !response.ok ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Translation with Elia failed. Error: ' +\n\t\t\t\t\tthis.getErrorName( response.status ) +\n\t\t\t\t\t` for ${ sourceLang } > ${ targetLang }: `\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst data = await response.json();\n\t\t\tthis.metrics.makeMetric( {\n\t\t\t\ttype: 'Counter',\n\t\t\t\tname: 'translate.Elia.charcount',\n\t\t\t\thelp: 'Elia character count'\n\t\t\t} ).increment( length );\n\t\t\tif ( 'translated_text' in data ) {\n\t\t\t\treturn data.translated_text;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Translation with Elia failed. Error: ${ this.getErrorName(\n\t\t\t\t\t\tdata.code || data\n\t\t\t\t\t) } for ${ sourceLang } > ${ targetLang }`\n\t\t\t\t);\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\tthrow new Error( `Translation with Elia ${ sourceLang } > ${ targetLang } failed: ${ error.message }` );\n\t\t}\n\t}\n\n\t/**\n\t * Returns error name from error code.\n\t *\n\t * @param {number} code Error code\n\t * @return {string}\n\t */\n\tgetErrorName( code ) {\n\t\tconst errormap = {\n\t\t\t403: 'Invalid api key'\n\t\t};\n\n\t\tif ( code in errormap ) {\n\t\t\treturn errormap[ code ];\n\t\t}\n\n\t\treturn `Unknown error: ${ code }`;\n\t}\n\n\trequiresAuthorization() {\n\t\treturn true;\n\t}\n}\n\nexport default Elia;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/Google.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":94,"column":27,"nodeType":"Identifier","messageId":"not-supported-till","endLine":94,"endColumn":32}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { ProxyAgent } from 'undici';\nimport { HTTPError } from '../util.js';\nimport MTClient from './MTClient.js';\n\n// Google language codes can differ from the language codes that we use.\nconst googleLanguageNameMap = {\n\tarz: 'ar', // T317224\n\t'be-tarask': 'be', // T122033\n\tbcl: 'bik', // T369815\n\tbho: 'bh', // Bhojpuri\n\tdgo: 'doi', // T369815\n\tgan: 'zh-TW', // T258919\n\the: 'iw', // Hebrew\n\tjv: 'jw', // Javanese\n\tknc: 'kr', // T369815\n\tmni: 'mni-Mtei', // Manipuri\n\tnb: 'no', // T132217\n\tnah: 'nhe', // T369815\n\tpnb: 'pa-Arab', // T369815\n\trwr: 'mwr', // T369815\n\tsimple: 'en', // Simple\n\tsh: 'bs', // T258919\n\ttw: 'ak', // Twi\n\twuu: 'zh', // T258919\n\tzh: 'zh-CN' // Chinese\n};\n\nclass Google extends MTClient {\n\t/**\n\t * Translate marked-up text\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} sourceHtml Source html\n\t * @return {Promise} Promise that resolves translated html\n\t */\n\ttranslate( sourceLang, targetLang, sourceHtml ) {\n\t\treturn this.translateReducedHtml( sourceLang, targetLang, sourceHtml );\n\t}\n\n\t/**\n\t * Translate html or plain text content with Google.\n\t * Google is capable of translating plain text and html with\n\t * annotations mapping (keeps markup retained in translated content).\n\t * Hence overriding translate method of MTClient.\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} sourceHtml Source language content\n\t * @return {Promise} Target language content\n\t */\n\tasync translateHtml( sourceLang, targetLang, sourceHtml ) {\n\t\tconst key = this.conf.mt.Google.key;\n\t\tif ( key === null ) {\n\t\t\tthrow new Error( 'Google service is misconfigured' );\n\t\t}\n\n\t\tconst length = sourceHtml.length;\n\t\tconst limit = 10000;\n\t\tif ( length > limit ) {\n\t\t\t// Max limit is 10K characters for Google.\n\t\t\tthrow new HTTPError( {\n\t\t\t\tstatus: 413,\n\t\t\t\ttype: 'mt_error',\n\t\t\t\tdetail: `Google: Source content too long: ${ length } (${ limit } is the character limit)`\n\t\t\t} );\n\t\t}\n\n\t\tsourceLang = googleLanguageNameMap[ sourceLang ] || sourceLang;\n\t\ttargetLang = googleLanguageNameMap[ targetLang ] || targetLang;\n\n\t\t// See https://cloud.google.com/translate/v2/translating-text-with-rest\n\t\tconst params = new URLSearchParams( {\n\t\t\tkey: key,\n\t\t\tsource: sourceLang,\n\t\t\ttarget: targetLang,\n\t\t\tformat: 'html',\n\t\t\tq: sourceHtml\n\t\t} );\n\n\t\tconst url = `${ this.conf.mt.Google.api }?${ params.toString() }`;\n\t\tconst options = {};\n\n\t\tif ( this.conf.proxy ) {\n\t\t\toptions.dispatcher = new ProxyAgent( this.conf.proxy, {\n\t\t\t\t// Ignore certificate errors from proxy server, if any.\n\t\t\t\trequestTls: {\n\t\t\t\t\trejectUnauthorized: false\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch( url, options );\n\t\t\tif ( !response.ok ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Translation with Google failed. Error: ${ response.status } for ${ sourceLang } > ${ targetLang }`\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst translatedData = await response.json();\n\t\t\tthis.metrics.makeMetric( {\n\t\t\t\ttype: 'Counter',\n\t\t\t\tname: 'translate.Google.charcount',\n\t\t\t\thelp: 'Google character count'\n\t\t\t} ).increment( length );\n\n\t\t\treturn translatedData.data.translations[ 0 ].translatedText;\n\t\t} catch ( error ) {\n\t\t\tthrow new Error( `Translation with Google ${ sourceLang } > ${ targetLang } failed: ${ error.message }` );\n\t\t}\n\t}\n\n\trequiresAuthorization() {\n\t\treturn true;\n\t}\n\n}\n\nexport default Google;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/LingoCloud.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":74,"column":27,"nodeType":"Identifier","messageId":"not-supported-till","endLine":74,"endColumn":32}],"suppressedMessages":[{"ruleId":"camelcase","severity":2,"message":"Identifier 'request_id' is not in camel case.","line":52,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":52,"endColumn":14,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'trans_type' is not in camel case.","line":54,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":54,"endColumn":14,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { ProxyAgent } from 'undici';\nimport { HTTPError } from '../util.js';\nimport MTClient from './MTClient.js';\n\nconst lingocloudLanguageNameMap = {\n\tsimple: 'en',\n\twuu: 'zh'\n};\n\n/**\n * Lingocloud Translation client\n * Spec: https://app.swaggerhub.com/apis/caiyun/lingo-cloud_api/1.0.1#/interpreter/post_translator\n * Doc: http://wiki.swarma.net/index.php/%E5%BD%A9%E4%BA%91%E5%B0%8F%E8%AF%91API/en\n */\nclass LingoCloud extends MTClient {\n\n\t/**\n\t * Translate plain text content with LingoCloud.\n\t * LingoCloud is not capable of translating html.\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} sourceText Source language text\n\t * @return {Promise} Target language text\n\t */\n\tasync translateText( sourceLang, targetLang, sourceText ) {\n\t\tconst key = this.conf.mt.LingoCloud.key;\n\t\tif ( key === null ) {\n\t\t\tthrow new Error( 'LingoCloud service is misconfigured' );\n\t\t}\n\n\t\tconst length = sourceText.length;\n\t\tconst limit = 10000;\n\t\tif ( length > limit ) {\n\t\t\tthrow new HTTPError( {\n\t\t\t\tstatus: 413,\n\t\t\t\ttype: 'mt_error',\n\t\t\t\tdetail: `LingoCloud: Source text too long: ${ length } (${ limit } is the limit)`\n\t\t\t} );\n\t\t}\n\n\t\tsourceLang = lingocloudLanguageNameMap[ sourceLang ] || sourceLang;\n\t\ttargetLang = lingocloudLanguageNameMap[ targetLang ] || targetLang;\n\n\t\tconst url = this.conf.mt.LingoCloud.api + '/translator';\n\t\tconst headers = {\n\t\t\t'x-authorization': `token ${ key }`,\n\t\t\t'content-type': 'application/json'\n\t\t};\n\t\t/* eslint-disable camelcase */\n\t\tconst body = {\n\t\t\trequest_id: this.conf.mt.LingoCloud.account,\n\t\t\treplaced: true,\n\t\t\ttrans_type: sourceLang + '2' + targetLang,\n\t\t\tsource: sourceText,\n\t\t\tmedia: 'text'\n\t\t};\n\t\tconst options = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: headers,\n\t\t\tbody: JSON.stringify( body )\n\t\t};\n\n\t\tif ( this.conf.proxy ) {\n\t\t\toptions.dispatcher = new ProxyAgent( this.conf.proxy, {\n\t\t\t\trequestTls: {\n\t\t\t\t\t// Ignore proxy certificate errors, if any.\n\t\t\t\t\trejectUnauthorized: false\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch( url, options );\n\t\t\tif ( !response.ok ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Translation with LingoCloud failed. Error: ' +\n\t\t\t\t\tthis.getErrorName( response.status ) +\n\t\t\t\t\t` for ${ sourceLang } > ${ targetLang }: `\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst data = await response.json();\n\t\t\tthis.metrics.makeMetric( {\n\t\t\t\ttype: 'Counter',\n\t\t\t\tname: 'translate.LingoCloud.charcount',\n\t\t\t\thelp: 'LingoCloud character count'\n\t\t\t} ).increment( length );\n\t\t\tif ( 'target' in data ) {\n\t\t\t\tconst target = data.target;\n\t\t\t\tif ( target instanceof Array ) {\n\t\t\t\t\treturn target.join( '' );\n\t\t\t\t} else {\n\t\t\t\t\treturn target;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} catch ( error ) {\n\t\t\tthrow new Error( `Translation with LingoCloud ${ sourceLang } > ${ targetLang } failed: ${ error.message }` );\n\t\t}\n\t}\n\n\t/**\n\t * Returns error name from error code.\n\t *\n\t * @param {number} code Error code\n\t * @return {string}\n\t */\n\tgetErrorName( code ) {\n\t\tconst errormap = {\n\t\t\t400: 'bad request',\n\t\t\t401: 'invalid token',\n\t\t\t402: 'blocked access token',\n\t\t\t403: 'api rate limit exceeded',\n\t\t\t415: 'wrong media type',\n\t\t\t500: 'internal server error',\n\t\t\t501: 'unsupported translation type'\n\t\t};\n\n\t\tif ( code in errormap ) {\n\t\t\treturn errormap[ code ];\n\t\t}\n\n\t\treturn `Unknown error: ${ code }`;\n\t}\n\n\trequiresAuthorization() {\n\t\treturn true;\n\t}\n}\n\nexport default LingoCloud;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/MTClient.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/MTClientError.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/MinT.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":55,"column":27,"nodeType":"Identifier","messageId":"not-supported-till","endLine":55,"endColumn":32}],"suppressedMessages":[{"ruleId":"camelcase","severity":2,"message":"Identifier 'source_language' is not in camel case.","line":46,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":46,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'target_language' is not in camel case.","line":48,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":48,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Agent } from 'undici';\nimport { isPlainText } from '../util.js';\nimport MTClient from './MTClient.js';\n\n// MinT language codes can differ from the language codes that wiki use.\n// Be agnostic of the domain code, language code differences, accept both,\n// map to the language code that the MinT server knows.\nconst mintLanguageNameMap = {\n\t'be-tarask': 'be', // T343450\n\tbho: 'bh', // Bhojpuri. https://bh.wikipedia.org has contentlanguage as bho\n\tnan: 'zh-min-nan', // T354666\n\tnb: 'no', // Accept both nb and no, and map to 'no' in MinT\n\tsimple: 'en', // Accept Simple English, map to English\n\tsh: 'bs', // T343450\n\twuu: 'zh' // T343450\n};\n\nclass MinT extends MTClient {\n\t/**\n\t * @inheritdoc\n\t */\n\tgetDelimiter() {\n\t\treturn '\\n';\n\t}\n\n\t/**\n\t * Translate the given content between the language pairs.\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} content Content to translate\n\t * @param {string} [format=\"html\"] Format of the content- html or text\n\t * @return {Promise} Deferred promise: Target language text\n\t */\n\tasync translate( sourceLang, targetLang, content, format = 'html' ) {\n\n\t\tif ( format === 'text' && !isPlainText( content ) ) {\n\t\t\tformat = 'html';\n\t\t}\n\n\t\tsourceLang = mintLanguageNameMap[ sourceLang ] || sourceLang;\n\t\ttargetLang = mintLanguageNameMap[ targetLang ] || targetLang;\n\n\t\tconst payload = {\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tsource_language: sourceLang,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\ttarget_language: targetLang,\n\t\t\tformat: format,\n\t\t\tcontent,\n\t\t\tstash: true\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await fetch( this.conf.mt.MinT.api, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify( payload ),\n\t\t\t\tdispatcher: new Agent( { connect: { timeout: 60_000 } } )\n\t\t\t} );\n\n\t\t\tif ( !response.ok ) {\n\t\t\t\tthrow new Error( `${ response.status }` );\n\t\t\t}\n\t\t\tthis.metrics.makeMetric( {\n\t\t\t\ttype: 'Counter',\n\t\t\t\tname: 'translate.MinT.charcount',\n\t\t\t\thelp: 'MinT character count'\n\t\t\t} ).increment( content.length );\n\n\t\t\tconst translationResponse = await response.json();\n\t\t\treturn translationResponse.translation;\n\t\t} catch ( error ) {\n\t\t\tthrow new Error( `Translation with MinT ${ sourceLang }>${ targetLang } failed: ${ error.message }` );\n\t\t}\n\t}\n\n}\n\nexport default MinT;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/TestClient.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/Yandex.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":82,"column":27,"nodeType":"Identifier","messageId":"not-supported-till","endLine":82,"endColumn":32}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { ProxyAgent } from 'undici';\nimport { HTTPError } from '../util.js';\nimport MTClient from './MTClient.js';\n\nconst yandexLanguageNameMap = {\n\t'be-tarask': 'be', // T122033\n\tnb: 'no', // T132217\n\tsimple: 'en', // T196354\n\tsh: 'bs', // T258919\n\twuu: 'zh' // T258919\n};\n\nclass Yandex extends MTClient {\n\t/**\n\t * Translate marked-up text\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} sourceHtml Source html\n\t * @return {Promise} Promise that resolves translated html\n\t */\n\ttranslate( sourceLang, targetLang, sourceHtml ) {\n\t\treturn this.translateReducedHtml( sourceLang, targetLang, sourceHtml );\n\t}\n\n\t/**\n\t * Translate html or plain text content with Yandex.\n\t * Yandex is capable of translating plain text and html with\n\t * annotations mapping (keeps markup retained in translated content).\n\t * Hence overriding translate method of MTClient.\n\t *\n\t * @param {string} sourceLang Source language code\n\t * @param {string} targetLang Target language code\n\t * @param {string} sourceHtml Source language content\n\t * @return {Promise} Target language text\n\t */\n\tasync translateHtml( sourceLang, targetLang, sourceHtml ) {\n\t\tconst key = this.conf.mt.Yandex.key;\n\t\tif ( key === null ) {\n\t\t\tthrow new Error( 'Yandex service is misconfigured' );\n\t\t}\n\n\t\tconst length = sourceHtml.length;\n\t\tconst limit = 10000;\n\t\tif ( length > limit ) {\n\t\t\t// Max limit is 10K characters for Yandex.\n\t\t\tthrow new HTTPError( {\n\t\t\t\tstatus: 413,\n\t\t\t\ttype: 'mt_error',\n\t\t\t\tdetail: `Yandex: Source content too long: ${ length } (${ limit } is the character limit)`\n\t\t\t} );\n\t\t}\n\n\t\tsourceLang = yandexLanguageNameMap[ sourceLang ] || sourceLang;\n\t\ttargetLang = yandexLanguageNameMap[ targetLang ] || targetLang;\n\t\tconst url = this.conf.mt.Yandex.api + '/api/v1.5/tr.json/translate';\n\t\tconst headers = {\n\t\t\t'Content-Type': 'application/x-www-form-urlencoded'\n\t\t};\n\t\tconst body = {\n\t\t\tkey,\n\t\t\tlang: sourceLang + '-' + targetLang,\n\t\t\tformat: 'html',\n\t\t\ttext: sourceHtml\n\t\t};\n\t\tconst options = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: headers,\n\t\t\tbody: new URLSearchParams( body )\n\t\t};\n\n\t\tif ( this.conf.proxy ) {\n\t\t\toptions.dispatcher = new ProxyAgent( this.conf.proxy, {\n\t\t\t\trequestTls: {\n\t\t\t\t\t// Ignore proxy certificate errors, if any.\n\t\t\t\t\trejectUnauthorized: false\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch( url, options );\n\t\t\tif ( !response.ok ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Translation with Yandex failed. Error: ' +\n\t\t\t\t\tthis.getErrorName( response.status ) +\n\t\t\t\t\t` for ${ sourceLang } > ${ targetLang }: `\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst data = await response.json();\n\t\t\tthis.metrics.makeMetric( {\n\t\t\t\ttype: 'Counter',\n\t\t\t\tname: 'translate.Yandex.charcount',\n\t\t\t\thelp: 'Yandex character count'\n\t\t\t} ).increment( length );\n\t\t\tif ( 'text' in data ) {\n\t\t\t\treturn data.text[ 0 ];\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Translation with Yandex failed for ${ sourceLang } > ${ targetLang } Error: ` +\n\t\t\t\t\tthis.getErrorName( data.code || data )\n\t\t\t\t);\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\tthrow new Error( `Translation with Yandex ${ sourceLang } > ${ targetLang } failed: ${ error.message }` );\n\t\t}\n\t}\n\n\t/**\n\t * Returns error name from error code.\n\t *\n\t * @param {number} code Error code\n\t * @return {string}\n\t */\n\tgetErrorName( code ) {\n\t\t// http://api.yandex.com/translate/doc/dg/reference/translate.xml\n\t\tconst errormap = {\n\t\t\t200: 'ERR_OK',\n\t\t\t401: 'ERR_KEY_INVALID',\n\t\t\t402: 'ERR_KEY_BLOCKED',\n\t\t\t403: 'ERR_DAILY_REQ_LIMIT_EXCEEDED',\n\t\t\t404: 'ERR_DAILY_CHAR_LIMIT_EXCEEDED',\n\t\t\t413: 'ERR_TEXT_TOO_LONG',\n\t\t\t422: 'ERR_UNPROCESSABLE_TEXT',\n\t\t\t501: 'ERR_LANG_NOT_SUPPORTED'\n\t\t};\n\n\t\tif ( code in errormap ) {\n\t\t\treturn errormap[ code ];\n\t\t}\n\n\t\treturn `Unknown error: ${ code }`;\n\t}\n\n\trequiresAuthorization() {\n\t\treturn true;\n\t}\n}\n\nexport default Yandex;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/annotationmapper/LevenshteinDistance.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/annotationmapper/SubsequenceMatcher.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mt/index.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/BatchedAPIRequest.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/MWApiRequestManager.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/MWPageLoader.js","messages":[{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":19,"column":33,"nodeType":"CallExpression","endLine":19,"endColumn":92}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * @external MTClient\n */\n\nimport { readFileSync } from 'fs';\nimport { load } from 'js-yaml';\nimport { Title } from 'mediawiki-title';\nimport { MwContextualizer, Parser } from '../lineardoc/index.js';\nimport CXSegmenter from '../segmentation/CXSegmenter.js';\nimport Adapter from '../Adapter.js';\nimport { getProp, HTTPError } from '../util.js';\nimport MWApiRequestManager from './MWApiRequestManager.js';\nimport ApiRequest from './MwApiRequest.js';\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\nclass MWPageLoader extends ApiRequest {\n\tconstructor( config ) {\n\t\tsuper( config );\n\t\tthis.pageloaderConfig = load( readFileSync( dirname + '/../../config/MWPageLoader.yaml' ) );\n\t}\n\n\t/**\n\t * @param {string} page The page title\n\t * @param {string} revision The revision id\n\t * @param {boolean} wrapSections Whether translatable sections should be wrapped in\n\t * <section> tag\n\t * @return {Promise}\n\t */\n\tgetPage( page, revision, wrapSections ) {\n\t\treturn this.fetch( page, revision ).then( ( response ) => {\n\t\t\tlet parsedDoc = this.getParsedDoc( response.body );\n\t\t\tif ( wrapSections ) {\n\t\t\t\tparsedDoc = parsedDoc.wrapSections();\n\t\t\t}\n\t\t\t// Extract category tags from source document.\n\t\t\tconst sourceCategoryTags = parsedDoc.categories;\n\t\t\tconst segmentedDoc = new CXSegmenter().segment( parsedDoc, this.sourceLanguage );\n\n\t\t\tif ( this.targetLanguage ) {\n\t\t\t\tconst api = new MWApiRequestManager( this.context, this.context.logger );\n\t\t\t\tconst adapter = new Adapter(\n\t\t\t\t\tthis.sourceLanguage, this.targetLanguage, api, this.context\n\t\t\t\t);\n\n\t\t\t\treturn this.adaptCategories( sourceCategoryTags, adapter ).then( ( categories ) => ( {\n\t\t\t\t\tcontent: segmentedDoc.getHtml(),\n\t\t\t\t\tcategories,\n\t\t\t\t\trevision: response.revision\n\t\t\t\t} ) );\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: segmentedDoc.getHtml(),\n\t\t\t\trevision: response.revision\n\t\t\t};\n\t\t} );\n\t}\n\n\t/**\n\t * @param {string} content\n\t * @param {boolean} wrapSections Whether translatable sections should be wrapped in\n\t * <section> tag\n\t * @return {Object}\n\t */\n\tgetParsedDoc( content, wrapSections ) {\n\t\tconst parser = new Parser( new MwContextualizer(\n\t\t\t{ removableSections: this.pageloaderConfig.removableSections }\n\t\t), {\n\t\t\twrapSections\n\t\t} );\n\t\tparser.init();\n\t\tparser.write( content );\n\t\treturn parser.builder.doc;\n\t}\n\n\t/**\n\t * @param {string} page The page title\n\t * @param {string} revision The revision id\n\t * @return {Promise}\n\t */\n\tasync fetch( page, revision ) {\n\t\tlet path;\n\t\tconst domain = this.getDomain( this.sourceLanguage );\n\n\t\tconst mwApi = new MWApiRequestManager( this.context, this.context.logger );\n\t\tconst siteInfo = await mwApi.siteInfoRequest( this.sourceLanguage );\n\n\t\tconst titleObject = Title.newFromText( page, siteInfo );\n\t\t// Manual normalisation to always transform multi-word page titles to underscore-separated titles\n\t\tconst title = titleObject.getPrefixedDBKey();\n\n\t\tif ( revision ) {\n\t\t\tpath = `/revision/${ revision }/html`;\n\t\t} else {\n\t\t\tpath = `/page/${ encodeURIComponent( title ) }/html`;\n\t\t}\n\n\t\tconst restReq = {\n\t\t\theaders: {\n\t\t\t\t// See https://www.mediawiki.org/wiki/Specs/HTML/2.8.0\n\t\t\t\taccept: 'text/html; charset=utf-8; profile=\"https://www.mediawiki.org/wiki/Specs/HTML/2.8.0\"'\n\t\t\t}\n\t\t};\n\n\t\treturn this.restApiGet( domain, path, restReq ).then( async ( response ) => {\n\t\t\tif ( !response.ok ) {\n\t\t\t\tthrow HTTPError.fromResponse( response );\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tbody: await response.text(),\n\t\t\t\trevision: response.headers.get( 'content-revision-id' )\n\t\t\t};\n\t\t} );\n\t}\n\n\tasync adaptCategories( sourceCategoryTags, adapter ) {\n\t\tconst categoryAdaptationRequests = [];\n\n\t\tfor ( let i = 0; i < sourceCategoryTags.length; i++ ) {\n\t\t\tconst translationunit = adapter.getAdapter( sourceCategoryTags[ i ] );\n\t\t\tconst request = translationunit.adapt( sourceCategoryTags[ i ] ).then( ( adaptedCategory ) => JSON.parse( adaptedCategory.attributes[ 'data-cx' ] ) );\n\t\t\tcategoryAdaptationRequests.push( request );\n\t\t}\n\n\t\treturn await Promise.all( categoryAdaptationRequests );\n\t}\n\n\t/**\n\t * Given a source title and an MTClient instance, this method returns a promise resolving\n\t * to an object that contains the source language,the target language, the source title and\n\t * the suggested target title. The suggested title is fetched from Wikidata API, if it exists\n\t * for the given target language. If not, the source title is translated using the given MTClient\n\t * for that language pair, and this translation is returned as suggested target title.\n\t * Finally, if the translation fails too, the source title is returned as suggested target title.\n\t *\n\t * @param {string} sourceTitle\n\t * @param {MTClient} mtClient\n\t * @return {Promise<{sourceLanguage: string, targetLanguage: string, sourceTitle: string, targetTitle: string}|null>}\n\t */\n\tasync fetchTargetTitle( sourceTitle, mtClient ) {\n\t\tconst api = new MWApiRequestManager( this.context, this.context.logger );\n\n\t\tconst sourceTitleInfo = await api.titleInfoRequest( sourceTitle, this.sourceLanguage );\n\t\tconst qid = getProp( [ 'pageprops', 'wikibase_item' ], sourceTitleInfo );\n\n\t\tif ( !qid ) {\n\t\t\treturn null;\n\t\t}\n\t\tconst wikidataLabel = await api.wikidataRequest( qid, this.targetLanguage );\n\t\tconst result = {\n\t\t\tsourceLanguage: this.sourceLanguage,\n\t\t\ttargetLanguage: this.targetLanguage,\n\t\t\tsourceTitle,\n\t\t\ttargetTitle: sourceTitle\n\t\t};\n\n\t\tif ( wikidataLabel ) {\n\t\t\tresult.targetTitle = wikidataLabel;\n\t\t} else if ( sourceTitle ) {\n\t\t\tconst translatedLabel = await mtClient.translate(\n\t\t\t\tthis.sourceLanguage,\n\t\t\t\tthis.targetLanguage,\n\t\t\t\tsourceTitle,\n\t\t\t\t'text'\n\t\t\t);\n\n\t\t\tif ( translatedLabel ) {\n\t\t\t\tresult.targetTitle = translatedLabel;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n}\nexport default MWPageLoader;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/MwApiRequest.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":60,"column":26,"nodeType":"Identifier","messageId":"not-supported-till","endLine":60,"endColumn":31},{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":106,"column":26,"nodeType":"Identifier","messageId":"not-supported-till","endLine":106,"endColumn":31},{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":193,"column":10,"nodeType":"Identifier","messageId":"not-supported-till","endLine":193,"endColumn":15}],"suppressedMessages":[{"ruleId":"camelcase","severity":2,"message":"Identifier 'mwapi_tpl' is not in camel case.","line":147,"column":16,"nodeType":"Identifier","messageId":"notCamelCase","endLine":147,"endColumn":25,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'restbase_tpl' is not in camel case.","line":153,"column":16,"nodeType":"Identifier","messageId":"notCamelCase","endLine":153,"endColumn":28,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * @external Application\n */\n\nimport { Agent } from 'undici';\nimport swaggerrouter from 'swagger-router';\nimport { HTTPError as _HTTPError } from '../util.js';\nimport languageDomainNameMapping from './../language-domain-mapping.json' assert { type: 'json' };\nconst HTTPError = _HTTPError;\nconst { Template } = swaggerrouter;\n\nclass MWApiRequest {\n\t/**\n\t * @param {Object} config Configuration options\n\t * @param {Object} config.context Application context\n\t * @param {string} config.sourceLanguage Source language\n\t * @param {string} [config.targetLanguage] target language\n\t */\n\tconstructor( config ) {\n\t\tthis.context = config.context;\n\t\t// Source and target languages\n\t\tthis.sourceLanguage = config.sourceLanguage;\n\t\tthis.targetLanguage = config.targetLanguage;\n\t\tthis.setupApiTemplates( config.context );\n\t}\n\n\t/**\n\t * Calls the MW API with the supplied query as its body\n\t *\n\t * @param {string} domain The domain to issue the request to\n\t * @param {Object} query An object with all the query parameters for the MW API\n\t * @return {Promise} A promise resolving as the response object from the MW API\n\t */\n\tasync mwPost( domain, query ) {\n\t\tquery = query || {};\n\t\tquery = Object.assign( {\n\t\t\tformat: 'json'\n\t\t}, query );\n\t\tconst request = this.context.mwapi_tpl.expand( {\n\t\t\trequest: {\n\t\t\t\tparams: {\n\t\t\t\t\tdomain: domain,\n\t\t\t\t\torigin: '*'\n\t\t\t\t},\n\t\t\t\theaders: {\n\t\t\t\t\t'user-agent': this.context.conf.user_agent,\n\t\t\t\t\t'content-type': 'application/x-www-form-urlencoded'\n\t\t\t\t},\n\t\t\t\tbody: query\n\t\t\t}\n\t\t} );\n\n\t\tconst options = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: request.headers,\n\t\t\tbody: JSON.stringify( request.body ),\n\t\t\tdispatcher: new Agent( { connect: { timeout: 60_000 } } )\n\t\t};\n\n\t\tconst response = await fetch( request.uri, options );\n\t\tif ( !response.ok ) {\n\t\t\t// there was an error when calling the upstream service, propagate that\n\t\t\tthrow new HTTPError( {\n\t\t\t\tstatus: response.status,\n\t\t\t\ttype: 'api_error',\n\t\t\t\tdetail: `MW API error from URL: ${ request.uri }`\n\t\t\t} );\n\t\t}\n\n\t\treturn await response.json();\n\t}\n\n\t/**\n\t * Calls the MW API with the supplied query as URL params\n\t *\n\t * @param {string} domain The domain to issue the request to\n\t * @param {Object} query An object with all the query parameters for the MW API\n\t * @return {Promise} A promise resolving as the response object from the MW API\n\t */\n\tasync mwGet( domain, query ) {\n\t\tquery = query || {};\n\t\tquery = Object.assign( {\n\t\t\tformat: 'json'\n\t\t}, query );\n\t\tconst request = this.context.mwapi_tpl.expand( {\n\t\t\trequest: {\n\t\t\t\tparams: {\n\t\t\t\t\tdomain: domain,\n\t\t\t\t\torigin: '*'\n\t\t\t\t},\n\t\t\t\theaders: {\n\t\t\t\t\t'user-agent': this.context.conf.user_agent\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\trequest.method = 'GET';\n\t\trequest.uri = `${ request.uri }?${ new URLSearchParams( query ).toString() }`;\n\n\t\tconst options = {\n\t\t\tmethod: 'GET',\n\t\t\theaders: request.headers,\n\t\t\tdispatcher: new Agent( { connect: { timeout: 60_000 } } )\n\t\t};\n\n\t\tconst response = await fetch( request.uri, options );\n\n\t\tif ( !response.ok ) {\n\t\t\t// there was an error when calling the upstream service, propagate that\n\t\t\tthrow new HTTPError( {\n\t\t\t\tstatus: response.status,\n\t\t\t\ttype: 'api_error',\n\t\t\t\tdetail: `MW API error from URL: ${ request.uri }`\n\t\t\t} );\n\t\t}\n\n\t\treturn await response.json();\n\n\t}\n\n\tgetDomain( language ) {\n\t\tconst code = this.getSiteCode( language );\n\t\treturn ( this.context.mw_host || '{lang}.wikipedia.org' ).replace( '{lang}', code );\n\t}\n\n\t/**\n\t * Resolve non-standard wikimedia site codes\n\t *\n\t * @param {string} language Language code\n\t * @return {string} Wikipedia site code corresponding to the language code.\n\t */\n\tgetSiteCode( language ) {\n\t\treturn languageDomainNameMapping[ language ] || language;\n\t}\n\n\t/**\n\t * Sets up the request templates for MW and RESTBase API requests\n\t *\n\t * @param {Application} app the application object\n\t */\n\tsetupApiTemplates( app ) {\n\t\t/* eslint-disable camelcase */\n\t\t// set up the MW API request template\n\t\tif ( !app.conf.mwapi_req ) {\n\t\t\tapp.logger.error( 'mwapi_req not found in configuration' );\n\t\t}\n\t\tthis.context.mwapi_tpl = new Template( this.context.conf.mwapi_req );\n\n\t\t// set up the RESTBase request template\n\t\tif ( !app.conf.restbase_req ) {\n\t\t\tapp.logger.error( 'restbase_req not found in configuration' );\n\t\t}\n\t\tthis.context.restbase_tpl = new Template( this.context.conf.restbase_req );\n\t\t/* eslint-enable camelcase */\n\t}\n\n\t/**\n\t * Calls the REST API with the supplied domain, path and request parameters\n\t *\n\t * @param {string} domain the domain to issue the request for\n\t * @param {string} path the REST API path to contact without the leading slash\n\t * @param {Object} [restReq={}] the object containing the REST request details\n\t * @param {string} [restReq.method=GET] the request method\n\t * @param {Object} [restReq.query={}] the query string to send, if any\n\t * @param {Object} [restReq.headers={}] the request headers to send\n\t * @param {Object} [restReq.body=null] the body of the request, if any\n\t * @return {Promise} a promise resolving as the response object from the REST API\n\t */\n\trestApiGet( domain, path, restReq ) {\n\t\trestReq = restReq || {};\n\t\tpath = path[ 0 ] === '/' ? path.slice( 1 ) : path;\n\t\tconst request = this.context.restbase_tpl.expand( {\n\t\t\trequest: {\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams: {\n\t\t\t\t\tdomain,\n\t\t\t\t\tpath\n\t\t\t\t},\n\t\t\t\tquery: restReq.query,\n\t\t\t\theaders: Object.assign( {\n\t\t\t\t\t'user-agent': this.context.conf.user_agent,\n\t\t\t\t\thost: domain\n\t\t\t\t}, restReq.headers )\n\t\t\t}\n\t\t} );\n\t\trequest.uri = `${ request.uri }?${ new URLSearchParams( request.query ).toString() }`;\n\t\tconst options = {\n\t\t\tmethod: request.method,\n\t\t\theaders: request.headers,\n\t\t\tdispatcher: new Agent( { connect: { timeout: 60_000 } } )\n\t\t};\n\n\t\treturn fetch( request.uri, options );\n\t}\n}\n\nexport default MWApiRequest;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/PageMetadataRequest.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/SiteInfoRequest.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/TemplateDataRequest.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/TitleInfoRequest.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/TitlePairRequest.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mw/WikidataRequest.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/routes/info.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/routes/root.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/routes/v1.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/routes/v2.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/segmentation/CXSegmenter.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/suggestion/SectionSuggester.js","messages":[],"suppressedMessages":[{"ruleId":"camelcase","severity":2,"message":"Identifier 'source_title' is not in camel case.","line":59,"column":20,"nodeType":"Identifier","messageId":"notCamelCase","endLine":59,"endColumn":32,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier 'target_title' is not in camel case.","line":63,"column":20,"nodeType":"Identifier","messageId":"notCamelCase","endLine":63,"endColumn":32,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/suggestion/SourceSuggester.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/suggestion/index.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/swagger-ui.js","messages":[{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFile from package \"fs\" with non literal argument at index 0","line":26,"column":9,"nodeType":"CallExpression","endLine":26,"endColumn":32}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { getAbsoluteFSPath } from 'swagger-ui-dist';\nimport { HTTPError } from '../lib/util.js';\n\n// Swagger-ui-dist helpfully exporting the absolute path of its dist directory\nconst docRoot = `${ getAbsoluteFSPath() }/`;\nconst DOC_CSP = \"default-src 'none'; \" +\n\t\"script-src 'self' 'unsafe-inline'; connect-src *; \" +\n\t\"style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';\";\n\nfunction processRequest( app, req, res ) {\n\tconst reqPath = req.query.path || '/index.html';\n\tconst filePath = join( docRoot, reqPath );\n\n\t// Disallow relative paths.\n\t// Test relies on docRoot ending on a slash.\n\tif ( filePath.slice( 0, docRoot.length ) !== docRoot ) {\n\t\tthrow new HTTPError( {\n\t\t\tstatus: 404,\n\t\t\ttype: 'not_found',\n\t\t\tdetail: `${ reqPath } could not be found.`\n\t\t} );\n\t}\n\n\treturn fs.readFile( filePath )\n\t\t.then( ( body ) => {\n\t\t\tif ( reqPath === './swagger-initializer.js' ) {\n\t\t\t\tbody = body.toString()\n\t\t\t\t\t.replace( /\"https:\\/\\/petstore.swagger.io\\/v2\\/swagger.json\"/g,\n\t\t\t\t\t\t'\"/?spec\"' );\n\t\t\t}\n\t\t\tif ( reqPath === '/index.html' ) {\n\t\t\t\tbody = body.toString()\n\t\t\t\t\t.replace( /((?:src|href)=['\"])/g, '$1?doc&path=' )\n\t\t\t\t\t.replace( /<title>[^<]*<\\/title>/, `<title>${ app.info.name }</title>` );\n\t\t\t}\n\n\t\t\tlet contentType = 'text/html';\n\t\t\tif ( /\\.js$/.test( reqPath ) ) {\n\t\t\t\tcontentType = 'text/javascript';\n\t\t\t} else if ( /\\.png$/.test( reqPath ) ) {\n\t\t\t\tcontentType = 'image/png';\n\t\t\t} else if ( /\\.map$/.test( reqPath ) ) {\n\t\t\t\tcontentType = 'application/json';\n\t\t\t} else if ( /\\.ttf$/.test( reqPath ) ) {\n\t\t\t\tcontentType = 'application/x-font-ttf';\n\t\t\t} else if ( /\\.css$/.test( reqPath ) ) {\n\t\t\t\tcontentType = 'text/css';\n\t\t\t\tbody = body.toString()\n\t\t\t\t\t.replace( /\\.\\.\\/(images|fonts)\\//g, '?doc&path=$1/' )\n\t\t\t\t\t.replace( /sourceMappingURL=/, 'sourceMappingURL=/?doc&path=' );\n\t\t\t}\n\n\t\t\tres.setHeader( 'Content-Type', contentType );\n\t\t\tres.header( 'content-security-policy', DOC_CSP );\n\t\t\tres.header( 'x-content-security-policy', DOC_CSP );\n\t\t\tres.header( 'x-webkit-csp', DOC_CSP );\n\t\t\tres.send( body.toString() );\n\t\t} )\n\t\t.catch( { code: 'ENOENT' }, () => {\n\t\t\tres.status( 404 )\n\t\t\t\t.type( 'not_found' )\n\t\t\t\t.send( 'not found' );\n\t\t} );\n\n}\n\nexport default {\n\tprocessRequest\n};\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/MWCategory.js","messages":[{"ruleId":"security/detect-unsafe-regex","severity":1,"message":"Unsafe Regular Expression","line":15,"column":41,"nodeType":"Literal","endLine":15,"endColumn":64}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import TranslationUnit from './TranslationUnit.js';\n\nclass MWCategory extends TranslationUnit {\n\tasync adapt() {\n\t\tconst dataCX = { adapted: false };\n\t\tconst categoryTitle = this.node.attributes.href;\n\t\tconst titlePairInfo = await this.api.titlePairRequest(\n\t\t\tcategoryTitle, this.sourceLanguage, this.targetLanguage\n\t\t);\n\n\t\tdataCX.sourceTitle = titlePairInfo.sourceTitle;\n\t\tif ( titlePairInfo.targetTitle ) {\n\t\t\tlet adaptedTitle = titlePairInfo.targetTitle;\n\t\t\tconst namespaceAlias = await this.api.getNamespaceAlias( 'Category', this.targetLanguage );\n\t\t\tadaptedTitle = adaptedTitle.replace( /^(\\.\\.?\\/)*([^:]+)(:)/, '$1' + namespaceAlias + '$3' );\n\t\t\tthis.node.attributes.href = adaptedTitle;\n\n\t\t\tdataCX.adapted = true;\n\t\t\tdataCX.targetTitle = titlePairInfo.targetTitle;\n\t\t}\n\n\t\tthis.node.attributes[ 'data-cx' ] = JSON.stringify( dataCX );\n\t\treturn this.node;\n\t}\n}\nMWCategory.matchTagNames = [ 'link' ];\nMWCategory.matchRdfaTypes = [ 'mw:PageProp/Category' ];\n\nexport default MWCategory;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/MWFile.js","messages":[{"ruleId":"security/detect-unsafe-regex","severity":1,"message":"Unsafe Regular Expression","line":44,"column":51,"nodeType":"Literal","endLine":44,"endColumn":74}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import TranslationUnit from './TranslationUnit.js';\nconst CommonsFilePathPrefix = '//upload.wikimedia.org/wikipedia/commons/';\n/**\n * This class is an adapter for <img>, <video> and <audio> nodes in the content.\n * It changes the `File` namespace prefix for resources to corresponding namespace\n * in target URL, if the resource is refering the file from Wikimedia commons.\n *\n * The node will get a new attribute data-cx with adapted key as true or false\n * depending on whether the namespace change happened or not.\n */\nclass MWFile extends TranslationUnit {\n\n\t/**\n\t * Check if an file is coming from Commons or not. Uses the URL pattern of the common file\n\t * repository to determine whether the file is stored there.\n\t *\n\t * @param {string} fileSrc\n\t * @return {boolean}\n\t */\n\tisCommonsResource( fileSrc ) {\n\t\treturn fileSrc.includes( CommonsFilePathPrefix );\n\t}\n\n\tasync adapt() {\n\t\tconst dataCX = { adapted: true };\n\t\tconst sourceResource = this.node.attributes.resource;\n\t\tlet resourceURL = this.node.attributes.src || this.node.attributes.poster;\n\t\tif ( !resourceURL && this.node.children ) {\n\t\t\tconst textChunks = this.node.children.textChunks;\n\t\t\tfor ( let i = 0, len = textChunks.length; i < len; i++ ) {\n\t\t\t\tconst chunk = textChunks[ i ];\n\t\t\t\tif ( chunk.inlineContent && chunk.inlineContent.name === 'source' ) {\n\t\t\t\t\tresourceURL = chunk.inlineContent.attributes.src;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( !resourceURL ) {\n\t\t\treturn this.node;\n\t\t}\n\n\t\tif ( this.isCommonsResource( resourceURL ) ) {\n\t\t\tconst namespaceAlias = await this.api.getNamespaceAlias( 'File', this.targetLanguage );\n\t\t\tconst targetResource = sourceResource.replace( /^(\\.\\.?\\/)*([^:]+)(:)/, '$1' + namespaceAlias + '$3' );\n\t\t\tthis.node.attributes.resource = targetResource;\n\t\t} else {\n\t\t\tdataCX.adapted = false;\n\t\t}\n\t\tthis.node.attributes[ 'data-cx' ] = JSON.stringify( dataCX );\n\n\t\treturn this.node;\n\t}\n}\n\nMWFile.matchTagNames = [\n\t'video',\n\t'audio',\n\t'img'\n];\n\nexport default MWFile;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/MWGallery.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/MWImage.js","messages":[{"ruleId":"security/detect-unsafe-regex","severity":1,"message":"Unsafe Regular Expression","line":123,"column":68,"nodeType":"Literal","endLine":123,"endColumn":91}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getDir } from '@wikimedia/language-data';\nimport TranslationUnit from './TranslationUnit.js';\nimport MWTemplate from './MWTemplate.js';\nconst CommonsFilePathPrefix = '//upload.wikimedia.org/wikipedia/commons/';\n\n/**\n * This class is an adapter for block images(<figure>) and inline images(<span>).\n * a) It changes the `File` namespace prefix for resources to corresponding namespace\n * in target URL, if the resource is refering the file from Wikimedia commons.\n * b) It flips the mw-halign-left or mw-halign-right classes depending language directionality\n * of source and target language\n * c) If the image is a link, the namespace in the link URL will be adapted for target language.\n *\n * The node will get a new attribute data-cx with adapted key as true or false\n * depending on whether the namespace change happened or not.\n */\nclass MWImage extends TranslationUnit {\n\tisInlineMediaWithCaption() {\n\t\t// Figure can also mean Video or Audio too. https://www.mediawiki.org/wiki/Specs/HTML/2.4.0#Audio/Video\n\t\treturn this.node.name === 'span' && this.node.attributes.typeof &&\n\t\t\tthis.node.attributes.typeof.match( /(^|\\s)(mw:File|mw:Image)\\b/ ) &&\n\t\t\tthis.node.attributes[ 'data-mw' ] &&\n\t\t\tJSON.parse( this.node.attributes[ 'data-mw' ] ).caption;\n\t}\n\n\t/**\n\t * Check if an image is coming from Commons or not. Uses the URL pattern of the common file\n\t * repository to determine whether the image is stored there.\n\t *\n\t * @param {string} imageSrc\n\t * @return {boolean}\n\t */\n\tisCommonsResource( imageSrc ) {\n\t\treturn imageSrc.includes( CommonsFilePathPrefix );\n\t}\n\n\t/**\n\t * Adapt the image's alignment settings for the target language.\n\t */\n\tadaptImageAlignment() {\n\n\t\tconst sourceDirection = getDir( this.sourceLanguage );\n\t\tconst targetDirection = getDir( this.targetLanguage );\n\n\t\tif ( sourceDirection === targetDirection ) {\n\t\t\t// Source and target languages has same directionality. Nothing to do\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this.node.attributes.class ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst classes = this.node.attributes.class.split( ' ' );\n\t\t// If the image has an explicit alignment class in HTML, this means that it has explicit\n\t\t// alignment defined in wiki syntax. It must be explicitly flipped if the target language's\n\t\t// direction is different.\n\t\tconst leftIndex = classes.indexOf( 'mw-halign-left' );\n\t\tconst rightIndex = classes.indexOf( 'mw-halign-right' );\n\t\tif ( leftIndex > -1 ) {\n\t\t\tclasses[ leftIndex ] = 'mw-halign-right';\n\t\t} else if ( rightIndex > -1 ) {\n\t\t\tclasses[ rightIndex ] = 'mw-halign-left';\n\t\t}\n\n\t\tthis.node.attributes.class = classes.join( ' ' );\n\t}\n\n\tasync adapt() {\n\t\tlet imageLink, sourceImage;\n\n\t\tif ( this.node.attributes.typeof.includes( 'mw:Transclusion' ) ) {\n\t\t\t// Node has typeof=\"mw:Transclusion mw:File\"\n\t\t\t// The image is generated by a template. So template adaptation will take care of it.\n\t\t\t// Bug: T298592\n\t\t\tconst adapter = new MWTemplate(\n\t\t\t\tthis.node, this.sourceLanguage, this.targetLanguage, this.api, this.context\n\t\t\t);\n\t\t\treturn adapter.adapt();\n\t\t}\n\t\tconst dataCX = { adapted: false };\n\n\t\tif ( this.isInlineMediaWithCaption() ) {\n\t\t\t// The image caption is in data-mw attribute.\n\t\t\tif ( this.context.mtClient ) {\n\t\t\t\t// This is an inline image, Adapting the caption alone.\n\t\t\t\tconst caption = JSON.parse( this.node.attributes[ 'data-mw' ] ).caption;\n\t\t\t\tconst translatedCaption = await this.context.mtClient.translate(\n\t\t\t\t\tthis.sourceLanguage, this.targetLanguage, caption\n\t\t\t\t);\n\t\t\t\tthis.node.attributes[ 'data-mw' ] = JSON.stringify( { caption: translatedCaption } );\n\t\t\t}\n\t\t\tdataCX.adapted = true;\n\t\t\tthis.node.attributes[ 'data-cx' ] = JSON.stringify( dataCX );\n\t\t\treturn this.node;\n\t\t}\n\n\t\t// The image is a block media or inline media without a caption.\n\n\t\tthis.adaptImageAlignment();\n\n\t\tif ( this.node.children ) {\n\t\t\tconst textChunks = this.node.children.textChunks;\n\t\t\tfor ( let i = 0, len = textChunks.length; i < len; i++ ) {\n\t\t\t\tconst chunk = this.node.children.textChunks[ i ];\n\t\t\t\tif ( chunk.tags[ 0 ] && chunk.tags[ 0 ].name === 'a' ) {\n\t\t\t\t\timageLink = chunk.tags[ 0 ];\n\t\t\t\t}\n\t\t\t\tif ( chunk.inlineContent && chunk.inlineContent.name === 'img' ) {\n\t\t\t\t\tsourceImage = chunk.inlineContent;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( !sourceImage ) {\n\t\t\t// This node is not a figure or span containing <img>. Could be audio or video\n\t\t\treturn this.node;\n\t\t}\n\n\t\tif ( sourceImage && this.isCommonsResource( sourceImage.attributes.src ) ) {\n\t\t\tconst namespaceAlias = await this.api.getNamespaceAlias( 'File', this.targetLanguage );\n\t\t\tconst targetResource = sourceImage.attributes.resource.replace( /^(\\.\\.?\\/)*([^:]+)(:)/, '$1' + namespaceAlias + '$3' );\n\n\t\t\t// Image does not have a link when it is created with \"link=\".\n\t\t\tif ( imageLink && imageLink.attributes.href ) {\n\t\t\t\timageLink.attributes.href = targetResource;\n\t\t\t}\n\t\t\tdataCX.adapted = true;\n\t\t}\n\n\t\tthis.node.attributes[ 'data-cx' ] = JSON.stringify( dataCX );\n\t\treturn this.node;\n\t}\n}\n\nMWImage.matchTagNames = [\n\t'figure',\n\t'span'\n];\n\nMWImage.matchRdfaTypes = [\n\t// mw:File(/.*)? will match figure or span containing images, video, and audio.\n\t// But in the adapt method we process only images. The <img>, <video> and <audio>\n\t// will be adapted by MWFile adapter module.\n\t'mw:File', 'mw:File/Thumb', 'mw:File/Frame', 'mw:File/Frameless',\n\t// TODO: Remove 'mw:Image(/.*)?' when version 2.4.0 of the content is no\n\t// longer supported\n\t'mw:Image', 'mw:Image/Thumb', 'mw:Image/Frame', 'mw:Image/Frameless'\n];\n\nexport default MWImage;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/MWLink.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/MWReference.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/MWTemplate.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/TranslationUnit.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/translationunits/index.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/util.js","messages":[{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":132,"column":23,"nodeType":"CallExpression","endLine":132,"endColumn":47}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * @external Application\n * @external Request\n * @external Router\n */\n\nimport { readFileSync } from 'fs';\nimport { load } from 'js-yaml';\n\n/**\n * Error instance wrapping HTTP error responses\n */\nclass HTTPError extends Error {\n\n\tconstructor( response ) {\n\t\tsuper();\n\t\tError.captureStackTrace( this, HTTPError );\n\n\t\tthis.name = this.constructor.name;\n\t\tthis.message = `${ response.status }`;\n\t\tif ( response.detail ) {\n\t\t\tthis.message += `: ${ response.detail }`;\n\t\t}\n\n\t\tif ( response.type ) {\n\t\t\tthis.message += `: ${ response.type }`;\n\t\t}\n\n\t\tObject.assign( this, response );\n\t}\n\n\t/**\n\t * @param {Response} httpResponse\n\t * @return {HTTPError}\n\t */\n\tstatic fromResponse( httpResponse ) {\n\t\treturn new HTTPError( {\n\t\t\tstatus: httpResponse.status,\n\t\t\ttype: 'api_error',\n\t\t\tdetail: `Error from URL: ${ httpResponse.url }; status: ${ httpResponse.statusText }`\n\t\t} );\n\t}\n}\n\nfunction responseTimeMetricsMiddleware( app ) {\n\t// Create a histogram metric for HTTP request duration\n\tconst requestDuration = {\n\t\ttype: 'Histogram',\n\t\tname: `${ app.conf.name }_express_router_request_duration_seconds`,\n\t\thelp: 'request duration handled by router in seconds',\n\t\tbuckets: [ 0.01, 0.05, 0.1, 0.3, 1 ],\n\t\tlabels: {\n\t\t\tnames: [ 'path', 'method', 'status' ]\n\t\t}\n\t};\n\t// Create the metric\n\t// This will return the existing metric if it already exists\n\tconst responseTimeMetric = app.metrics.makeMetric( requestDuration );\n\tapp.logger.info( 'responseTimeMetric', responseTimeMetric.labels );\n\treturn ( req, res, next ) => {\n\t\tconst start = process.hrtime();\n\t\tconst originalEnd = res.end;\n\n\t\tres.end = ( ...args ) => {\n\t\t\t// Calculate the duration\n\t\t\tconst diff = process.hrtime( start );\n\t\t\tconst duration = diff[ 0 ] + diff[ 1 ] / 1e9;\n\n\t\t\tconst path = req.route ? req.route.path : req.path;\n\t\t\t// Observe the duration\n\t\t\tresponseTimeMetric.observe(\n\t\t\t\t{\n\t\t\t\t\tmethod: req.method,\n\t\t\t\t\tpath: path,\n\t\t\t\t\tstatus: res.statusCode\n\t\t\t\t},\n\t\t\t\tduration\n\t\t\t);\n\t\t\t// Call the original end function\n\t\t\toriginalEnd.apply( res, args );\n\t\t};\n\t\t// Continue processing the request\n\t\tnext();\n\t};\n}\n\nfunction Deferred() {\n\tthis.promise = new Promise( ( ( resolve, reject ) => {\n\t\tthis.resolve = resolve;\n\t\tthis.reject = reject;\n\t} ) );\n\n\tthis.then = this.promise.then.bind( this.promise );\n\tthis.catch = this.promise.catch.bind( this.promise );\n}\n\n/**\n * Check if the given content is plain text or contains html tags.\n * The check is performed by looking for open and close tags.\n * If the content has HTML entities, this test will not identify it.\n *\n * @param {string} content The content to test\n * @return {boolean} Return true if the content is plain text\n */\nfunction isPlainText( content ) {\n\treturn !content || !content.trim() || !/<[a-zA-Z][\\s\\S]*>/i.test( content );\n}\n\n/**\n * Null safe object getter\n * Example: To access obj.a.b.c[0].d in null safe way,\n * use getProp(['a', 'b', 'c', 0, 'd'], obj )\n *\n * @param {string|number} path access path\n * @param {Object} obj Object\n * @return {Object|string|number|null}\n */\nfunction getProp( path, obj ) {\n\treturn path.reduce(\n\t\t( accumulator, currentValue ) => ( accumulator && accumulator[ currentValue ] ) ?\n\t\t\taccumulator[ currentValue ] :\n\t\t\tnull,\n\t\tobj\n\t);\n}\n\nfunction getConfig( confPath ) {\n\tif ( !confPath ) {\n\t\tconst dirname = new URL( '.', import.meta.url ).pathname;\n\t\tconfPath = `${ dirname }/../config.dev.yaml`;\n\t}\n\tconst config = load( readFileSync( confPath ) );\n\tif ( !config ) {\n\t\tthrow new Error( 'Failed to load config from path: ' + confPath );\n\t}\n\treturn config;\n}\n\nexport {\n\tHTTPError,\n\tgetConfig,\n\tresponseTimeMetricsMiddleware,\n\tgetProp,\n\tDeferred,\n\tisPlainText\n};\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package-lock.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/package.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/scripts/SectionTitleAlignment/alignwithmt.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20'.","line":214,"column":26,"nodeType":"Identifier","messageId":"not-supported-till","endLine":214,"endColumn":31}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { readFileSync } from 'fs';\nimport { open } from 'sqlite';\n// sqlite3 is a dependency of sqlite. We can use sqlite3 alone if we raise our\n// minimum node version support to 11+. Currently it is 10.\nimport { Database, OPEN_READONLY, OPEN_READWRITE } from 'sqlite3';\nimport { load } from 'js-yaml';\nimport * as MTClients from '../../lib/mt/index.js';\nimport PrometheusClient from '../../lib/metric.js';\n\n/**\n * Align section titles in one language with section titles in another language.\n * This alignment is used for suggesting missing sections across articles in\n * different languages.\n * Here we use Machine translation to fill the title alignment.\n */\nclass AlignWithMT {\n\t/**\n\t * Creates an instance of AlignWithMT.\n\t *\n\t * @param {Object} cxConf\n\t * @memberof AlignWithMT\n\t */\n\tconstructor( cxConf ) {\n\t\tthis.cxConfig = cxConf;\n\t\tthis.sectionMappingDatabase = cxConf.sectionmapping.database;\n\t\tif ( !this.sectionMappingDatabase ) {\n\t\t\tthrow new Error( 'Section mapping database is not configured' );\n\t\t}\n\t}\n\n\tasync run() {\n\t\t// Find frequently used section titles in English.\n\t\tconst frequentSectionTitles = await this.findFrequentSectionTitles( this.sectionMappingDatabase, 'en' );\n\t\tconsole.log( `Found ${ frequentSectionTitles.length } frequent section titles` );\n\n\t\t// Find all target languages\n\t\tconst targetLanguages = await this.findTargetLanguages( this.sectionMappingDatabase );\n\t\tconsole.log( `Found ${ targetLanguages.length } target languages` );\n\n\t\tfor ( let i = 0; i < targetLanguages.length; i++ ) {\n\t\t\tconst sourceLanguage = 'en';\n\t\t\tconst targetLanguage = targetLanguages[ i ];\n\n\t\t\tconst missingTitles = await this.findMissingAlignment( this.sectionMappingDatabase, 'en', targetLanguages[ i ], frequentSectionTitles );\n\t\t\tconsole.log( `Missing titles for en -> ${ targetLanguages[ i ] }: ${ missingTitles.length }` );\n\t\t\tif ( !missingTitles.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Machine translate the missing section title using a service(if any)\n\t\t\t// and add to the database\n\t\t\t/* @type {string[]} */\n\t\t\tconst MTServices = await this.getMTService( 'en', targetLanguages[ i ] );\n\t\t\tif ( !MTServices || MTServices.length === 0 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Use the default service from the list of available services\n\t\t\tconst serviceName = MTServices[ 0 ];\n\t\t\tconst alignment = {};\n\t\t\tfor ( let j = 0; j < missingTitles.length; j++ ) {\n\t\t\t\tconst translation = await this.mt( serviceName, sourceLanguage, targetLanguage, missingTitles[ j ] );\n\t\t\t\tif ( missingTitles[ j ] !== translation ) {\n\t\t\t\t\talignment[ missingTitles[ j ] ] = translation;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconsole.log( `[${ serviceName }] ${ sourceLanguage }->${ targetLanguage }` );\n\t\t\tif ( Object.keys( alignment ).length ) {\n\t\t\t\tconsole.table( alignment );\n\t\t\t} else {\n\t\t\t\tconsole.log( 'Could not calculate any alignment using machine translation' );\n\t\t\t}\n\n\t\t\t// Insert this alignment to the database.\n\t\t\tawait this.addTitleAlignmentToDb( this.sectionMappingDatabase, sourceLanguage, targetLanguage, alignment );\n\t\t}\n\t}\n\n\t/**\n\t * Find frequently used section titles in a given language.\n\t *\n\t * @param {string} sectionMappingDatabase Database path\n\t * @param {string} sourceLanguage Source language code\n\t * @return {string[]}\n\t */\n\tasync findFrequentSectionTitles( sectionMappingDatabase, sourceLanguage ) {\n\t\tconst titles = [];\n\t\tconst db = await open( {\n\t\t\tfilename: sectionMappingDatabase,\n\t\t\tdriver: Database,\n\t\t\tmode: OPEN_READONLY\n\t\t} );\n\t\tconst query = `select source_title,\n\t\t\tcount(source_title) as occurrences\n\t\t\tfrom titles where source_language=?\n\t\t\tgroup by source_title\n\t\t\torder by occurrences desc\n\t\t\tlimit 200`;\n\t\tconst results = await db.all( query, [ sourceLanguage ] );\n\t\tfor ( let i = 0; i < results.length; i++ ) {\n\t\t\ttitles.push( results[ i ].source_title );\n\t\t}\n\t\tawait db.close();\n\n\t\treturn titles;\n\t}\n\n\t/**\n\t * Find most used target languages\n\t *\n\t * @param {string} sectionMappingDatabase Database path\n\t * @param {string} sourceLanguage Source language\n\t * @param {string} targetLanguage Target language\n\t * @param {string[]} sectionTitles\n\t * @return {string[]}\n\t */\n\tasync findMissingAlignment( sectionMappingDatabase, sourceLanguage, targetLanguage, sectionTitles ) {\n\t\t// Clone the sectionTitles for local modification\n\t\tconst titles = [ ...sectionTitles ];\n\t\tconst db = await open( {\n\t\t\tfilename: sectionMappingDatabase,\n\t\t\tdriver: Database,\n\t\t\tmode: OPEN_READONLY\n\t\t} );\n\t\tconst query = `SELECT DISTINCT source_title\n\t\t\tfrom titles\n\t\t\twhere source_language=?\n\t\t\tAND target_language=?\n\t\t\tAND source_title IN (${ sectionTitles.map( () => '?' ) })\n\t\t\tORDER BY source_title, frequency DESC`;\n\n\t\tconst results = await db.all( query, [ sourceLanguage, targetLanguage, ...sectionTitles ] );\n\t\tfor ( let i = 0; i < results.length; i++ ) {\n\t\t\tconst index = titles.indexOf( results[ i ].source_title );\n\t\t\tif ( index >= 0 ) {\n\t\t\t\ttitles.splice( index, 1 );\n\t\t\t}\n\t\t}\n\t\tawait db.close();\n\n\t\treturn titles;\n\t}\n\n\t/**\n\t * Find most used target languages\n\t *\n\t * @param {string} sectionMappingDatabase Database path\n\t * @return {string[]}\n\t */\n\tasync findTargetLanguages( sectionMappingDatabase ) {\n\t\tconst languages = [];\n\t\tconst db = await open( {\n\t\t\tfilename: sectionMappingDatabase,\n\t\t\tdriver: Database,\n\t\t\tmode: OPEN_READONLY\n\t\t} );\n\t\tconsole.log( 'findTargetLanguages' );\n\t\tconst query = `select target_language, count(source_title) as occurrences\n\t\t\tFROM titles\n\t\t\tGROUP BY target_language\n\t\t\tORDER BY occurrences desc\n\t\t\tlimit 200;`;\n\t\tconst results = await db.all( query );\n\t\tconsole.log( results.length );\n\t\tfor ( let i = 0; i < results.length; i++ ) {\n\t\t\t// Skip English\n\t\t\tif ( results[ i ].target_language === 'en' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlanguages.push( results[ i ].target_language );\n\t\t}\n\t\tawait db.close();\n\t\treturn languages;\n\t}\n\n\t/**\n\t * Insert section title mapping for a language pair\n\t *\n\t * @param {string} sectionMappingDatabase Database path\n\t * @param {string} sourceLanguage Source language\n\t * @param {string} targetLanguage Target language\n\t * @param {Object} titleMapping\n\t */\n\tasync addTitleAlignmentToDb( sectionMappingDatabase, sourceLanguage, targetLanguage, titleMapping ) {\n\t\tconst db = await open( {\n\t\t\tfilename: sectionMappingDatabase,\n\t\t\tdriver: Database,\n\t\t\tmode: OPEN_READWRITE\n\t\t} );\n\n\t\tconst query = 'INSERT INTO titles VALUES(?,?,?,?, ?)';\n\t\t// We set a special frequency value for MT calculated alignment. This is actually\n\t\t// arbitrary, but somewhat close to a possibly valid translation in comparison with\n\t\t// high frequency translation by a human translations.\n\t\tconst frequency = 100;\n\t\tfor ( const sourceTitle in titleMapping ) {\n\t\t\tconst targetTitle = titleMapping[ sourceTitle ];\n\t\t\tawait db.run( query, [ sourceLanguage, targetLanguage, sourceTitle, targetTitle, frequency ] );\n\t\t}\n\t\tawait db.close();\n\t}\n\n\t/**\n\t * Find the MT services available for given language pair.\n\t *\n\t * @param {string} sourceLanguage Source language\n\t * @param {string} targetLanguage Target language\n\t * @return {string[]}\n\t */\n\tasync getMTService( sourceLanguage, targetLanguage ) {\n\t\t// We can find the available MT services by using the cxserver registry.\n\t\t// But instantiating that is quite complex outside a server context.\n\t\t// To save the effort, rely on public API endpoint of cxserver.\n\t\tconst response = await fetch( `https://cxserver.wikimedia.org/v2/list/mt/${ sourceLanguage }/${ targetLanguage }` );\n\t\tconst data = await response.json();\n\t\treturn data.mt;\n\t}\n\n\t/**\n\t * Machine translate the given text for given language pair using given MT service.\n\t *\n\t * @param {string} serviceName\n\t * @param {string} sourceLanguage Source language\n\t * @param {string} targetLanguage Target language\n\t * @param {string} text Text to translate.\n\t * @return {string}\n\t */\n\tasync mt( serviceName, sourceLanguage, targetLanguage, text ) {\n\t\tconst mt = new MTClients[ serviceName ]( this.cxConfig );\n\t\treturn await mt.translate( sourceLanguage, targetLanguage, text );\n\t}\n}\n\nconst config = load( readFileSync( 'config.yaml' ) );\nif ( !config ) {\n\tthrow new Error( 'Failed to load config' );\n}\n\nconst cxConfig = config.services && Array.isArray( config.services ) &&\n\tconfig.services.filter( ( item ) => item && item.name === 'cxserver' )[ 0 ];\nif ( !cxConfig ) {\n\tthrow new Error( 'Cannot find cxserver config' );\n}\ncxConfig.metrics = new PrometheusClient( {\n\tstaticLabels: { service: 'cxserver' }\n} );\n\nconst alignWithMT = new AlignWithMT( cxConfig );\nalignWithMT.run();\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/scripts/template-mapping.js","messages":[{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found existsSync from package \"fs\" with non literal argument at index 0","line":108,"column":7,"nodeType":"CallExpression","endLine":108,"endColumn":26},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":114,"column":14,"nodeType":"CallExpression","endLine":114,"endColumn":35}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { existsSync, readFileSync } from 'fs';\nimport { ArgumentParser } from 'argparse';\nimport { open } from 'sqlite';\nimport { Database } from 'sqlite3';\n\nasync function createTemplate( db, from, to, templateName ) {\n\tconst mapping = await db.get(\n\t\t`SELECT id FROM templates\n WHERE source_lang = ? AND target_lang = ? AND template = ?`,\n\t\tfrom, to, templateName\n\t);\n\tif ( mapping && mapping.template_mapping_id ) {\n\t\treturn mapping.template_mapping_id;\n\t}\n\tconst result = await db.run(\n\t\t`INSERT OR IGNORE INTO templates\n (source_lang, target_lang, template) VALUES(?,?,?)`,\n\t\tfrom, to, templateName\n\t);\n\treturn result.lastID;\n}\n\nasync function main( databaseFile, mapping, from, to ) {\n\tconst db = await open( { filename: databaseFile, driver: Database } );\n\n\tawait db.run(\n\t\t`CREATE TABLE IF NOT EXISTS templates (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_lang TEXT NOT NULL,\n target_lang TEXT NOT NULL,\n template TEXT NOT NULL,\n UNIQUE(source_lang, target_lang, template)\n )`\n\t);\n\tawait db.run(\n\t\t`CREATE TABLE IF NOT EXISTS mapping (\n template_mapping_id INTEGER NOT NULL,\n source_param TEXT NOT NULL,\n target_param TEXT NOT NULL,\n score REAL NOT NULL,\n FOREIGN KEY(template_mapping_id) REFERENCES templates(id),\n UNIQUE(template_mapping_id, source_param, target_param)\n )`\n\t);\n\n\tfor ( const templateName in mapping ) {\n\t\tconst mappingData = mapping[ templateName ];\n\t\tif ( !mappingData || !mappingData.length ) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst mappingId = await createTemplate( db, from, to, templateName );\n\t\tprocess.stdout.write( `${ mappingId } ${ from } -> ${ to } ${ templateName }\\n` );\n\t\tfor ( const index in mappingData ) {\n\t\t\tconst paramMapping = mappingData[ index ];\n\t\t\tif ( !mappingId || !paramMapping[ from ] || !paramMapping[ to ] ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst score = 1 - paramMapping.d;\n\t\t\tdb.run(\n\t\t\t\t`INSERT OR IGNORE INTO mapping\n (template_mapping_id, source_param, target_param, score)\n VALUES(?,?,?,?)`,\n\t\t\t\tmappingId, paramMapping[ from ], paramMapping[ to ], score\n\t\t\t);\n\t\t\tprocess.stdout.write( `\\t${ paramMapping[ from ] } -> ${ paramMapping[ to ] } (${ score })\\n` );\n\t\t}\n\t}\n\tawait db.close();\n}\n\nconst argparser = new ArgumentParser( {\n\tadd_help: true,\n\tdescription: 'Prepare template mapping database'\n} );\n\nargparser.add_argument(\n\t'-d', '--database',\n\t{\n\t\thelp: 'template mapping database file',\n\t\tdefault: 'templatemapping.db'\n\t}\n);\nargparser.add_argument(\n\t'-i', '--input',\n\t{\n\t\thelp: 'JSON file with mapping.',\n\t\trequired: true\n\t}\n);\nargparser.add_argument(\n\t'--from',\n\t{\n\t\thelp: 'Source language',\n\t\trequired: true\n\t}\n);\nargparser.add_argument(\n\t'--to',\n\t{\n\t\thelp: 'Target language',\n\t\trequired: true\n\t}\n);\nconst args = argparser.parse_args();\n\nconst input = args.input;\nif ( !existsSync( input ) ) {\n\tthrow new Error( `File ${ input } does not exist` );\n}\n\nmain(\n\targs.database,\n\tJSON.parse( readFileSync( input ) ),\n\targs.from,\n\targs.to\n);\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/server.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/spec.yaml","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 139. Maximum allowed is 100.","line":195,"column":1,"nodeType":"Program","messageId":"max","endLine":195,"endColumn":140},{"ruleId":"max-len","severity":1,"message":"This line has a length of 139. Maximum allowed is 100.","line":246,"column":1,"nodeType":"Program","messageId":"max","endLine":246,"endColumn":140},{"ruleId":"max-len","severity":1,"message":"This line has a length of 109. Maximum allowed is 100.","line":468,"column":1,"nodeType":"Program","messageId":"max","endLine":468,"endColumn":110},{"ruleId":"max-len","severity":1,"message":"This line has a length of 110. Maximum allowed is 100.","line":493,"column":1,"nodeType":"Program","messageId":"max","endLine":493,"endColumn":111},{"ruleId":"max-len","severity":1,"message":"This line has a length of 216. Maximum allowed is 100.","line":499,"column":1,"nodeType":"Program","messageId":"max","endLine":499,"endColumn":217},{"ruleId":"max-len","severity":1,"message":"This line has a length of 110. Maximum allowed is 100.","line":540,"column":1,"nodeType":"Program","messageId":"max","endLine":540,"endColumn":111},{"ruleId":"max-len","severity":1,"message":"This line has a length of 216. Maximum allowed is 100.","line":547,"column":1,"nodeType":"Program","messageId":"max","endLine":547,"endColumn":217},{"ruleId":"max-len","severity":1,"message":"This line has a length of 106. Maximum allowed is 100.","line":589,"column":1,"nodeType":"Program","messageId":"max","endLine":589,"endColumn":107},{"ruleId":"max-len","severity":1,"message":"This line has a length of 134. Maximum allowed is 100.","line":606,"column":1,"nodeType":"Program","messageId":"max","endLine":606,"endColumn":135}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":9,"fixableErrorCount":0,"fixableWarningCount":0,"source":"openapi: 3.0.1\ninfo:\n version: 0.2.1\n title: Content translation service\n description: Content translation service for translating mediawiki pages between languages.\n termsOfService: https://wikimediafoundation.org/wiki/Terms_of_Use\n contact:\n name: the Wikimedia Language team\n url: https://www.mediawiki.org/wiki/Wikimedia_Language_engineering\n license:\n name: GPL-2.0-or-later\n url: http://opensource.org/licenses/GPL-2.0\nx-default-params:\n domain: en.wikipedia.org\n\npaths:\n # from routes/root.js\n /robots.txt:\n get:\n tags:\n - Root\n - Robots\n summary: Gets robots.txt\n responses:\n 200:\n description: Success\n content:\n text/plain:\n example:\n \"User-agent: * \\nDisallow: /\"\n x-amples:\n - title: robots.txt check\n request: {}\n response:\n status: 200\n /:\n get:\n tags:\n - Root\n summary: The root service end-point\n responses:\n 200:\n description: Success\n x-amples:\n - title: root with no query params\n request: {}\n response:\n status: 302\n - title: spec from root\n request:\n query:\n spec: true\n response:\n status: 200\n - title: doc from root\n request:\n query:\n doc: true\n response:\n status: 302\n - title: root with wrong query param\n request:\n query:\n fooo: true\n response:\n status: 302\n # from routes/v1.js\n /v1/page/{language}/{title}:\n get:\n tags:\n - Page content\n summary: Fetches segmented mediawiki page\n parameters:\n - $ref: \"#/components/parameters/language\"\n - $ref: \"#/components/parameters/title\"\n responses:\n 200:\n description: Page fetched successfully\n content:\n application/json:\n schema:\n type: object\n properties:\n sourceLanguage:\n type: string\n example: es\n title:\n type: string\n example: Albert Einstein\n revision:\n type: string\n example: 165157183\n segmentedContent:\n type: string\n example: lorem ipsum\n 404:\n description: Page not found\n x-amples:\n - title: Fetch enwiki protected page\n request:\n params:\n language: en\n title: User:BSitzmann_(WMF)/MCS/Test/Frankenstein\n response:\n status: 200\n headers:\n content-type: application/json\n - title: Fetch protected page with multi-word title\n request:\n params:\n language: en\n title: User:BSitzmann_(WMF)/MCS/Test/Frankenstein\n response:\n status: 200\n headers:\n content-type: application/json\n /v1/page/{language}/{title}/{revision}:\n get:\n tags:\n - Page content\n summary: Fetches segmented mediawiki page with revision\n parameters:\n - $ref: \"#/components/parameters/language\"\n - $ref: \"#/components/parameters/title\"\n - $ref: \"#/components/parameters/revision\"\n responses:\n 200:\n description: Success\n content:\n application/json:\n schema:\n type: object\n properties:\n sourceLanguage:\n type: string\n example: en\n title:\n type: string\n example: Albert Einstein\n revision:\n type: string\n example: 1234565\n segmentedContent:\n type: string\n example: lorem ipsum\n 404:\n description: Page not found\n x-amples:\n - title: Fetch enwiki protected page with revision\n request:\n params:\n language: en\n title: User:BSitzmann_(WMF)/MCS/Test/Frankenstein\n revision: 1086816359\n response:\n status: 200\n headers:\n content-type: application/json\n /v1/mt/{from}/{to}:\n post:\n tags:\n - Machine translation\n summary: Fetches the machine translation. Some providers require an authorization header\n and it is forbidden to use them outside the Content Translation tool.\n parameters:\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n requestBody:\n content:\n application/json:\n schema:\n required:\n - html\n example:\n hello world:\n value: { html: <p>hello world</p> }\n\n responses:\n 200:\n description: Machine translation fetched successfully\n content:\n application/json:\n examples:\n hello world:\n value: { html: <p>Bonjour le monde</p> }\n 500:\n description: Internal error\n x-amples:\n - title: Machine translate an HTML fragment using TestClient.\n request:\n params:\n from: en\n to: qqq\n body:\n html: <p><a href='Oxygen'>Oxygen</a> is a chemical element with symbol O and <a href='Atomic number'>atomic number</a> 8.</p>\n response:\n status: 200\n body:\n contents: /.+/\n headers:\n content-type: application/json\n /v1/mt/{from}/{to}/{mtprovider}:\n post:\n tags:\n - Machine translation\n summary: Fetches the machine translation. Some providers require an authorization header\n and it is forbidden to use them outside the Content Translation tool.\n parameters:\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n - $ref: \"#/components/parameters/mtprovider\"\n requestBody:\n content:\n application/json:\n schema:\n required:\n - html\n properties:\n html:\n type: string\n description: The HTML content to translate\n x-textarea: true\n examples:\n hello world:\n value: { html: <p>hello world</p> }\n Let's translate:\n value: { html: <p>Let's translate this paragraph.</p> }\n responses:\n 200:\n description: Machine translation fetched successfully\n content:\n application/json:\n examples:\n hello world:\n value: { html: <p>Bonjour le monde</p> }\n 400:\n description: Not found\n x-amples:\n - title: Machine translate an HTML fragment using TestClient.\n request:\n params:\n from: en\n to: qqq\n provider: TestClient\n body:\n html: <p><a href='Oxygen'>Oxygen</a> is a chemical element with symbol O and <a href='Atomic number'>atomic number</a> 8.</p>\n response:\n status: 200\n body:\n contents: /.+/\n headers:\n content-type: application/json\n /v1/list/pair/{from}/{to}:\n get:\n tags:\n - Tools\n summary: Lists the tools for a given language pair\n parameters:\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n responses:\n 200:\n description: Lists the tools for a given language pair fetched successfully\n content:\n application/json:\n schema:\n type: object\n properties:\n mt:\n type: array\n items:\n type: string\n example: { mt: [ Google, Elia, MinT, Yandex ] }\n 500:\n description: Internal error\n x-amples:\n - title: Get the tools between two language pairs\n request:\n params:\n from: en\n to: es\n response:\n status: 200\n headers:\n content-type: application/json\n /v1/list/languagepairs:\n get:\n tags:\n - Languages\n - Service information\n summary: Lists the language pairs supported by the server\n responses:\n 200:\n description: Success\n content:\n application/json:\n schema:\n type: object\n properties:\n sources:\n type: array\n items:\n type: string\n description: Source language code\n x-amples:\n - title: Get all the language pairs\n response:\n status: 200\n headers:\n content-type: application/json\n /v1/list/{tool}:\n get:\n tags:\n - Tools\n - Service information\n summary: Lists all language pairs that tool supports.\n parameters:\n - $ref: \"#/components/parameters/tool\"\n responses:\n 200:\n description: List of all language pairs\n content:\n application/json:\n schema:\n type: object\n properties:\n sources:\n type: object\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Get the MT tool between two language pairs\n request:\n params:\n tool: mt\n response:\n status: 200\n headers:\n content-type: application/json\n /v1/list/{tool}/{from}/{to}:\n get:\n tags:\n - Tools\n - Service information\n summary: Lists the providers for the tool in that language pair.\n parameters:\n - $ref: \"#/components/parameters/tool\"\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n responses:\n 200:\n description: List mt tools available for the language pairs\n content:\n application/json:\n schema:\n type: object\n properties:\n mt:\n type: array\n items:\n type: string\n example: { mt: [ Google, Elia, MinT, Yandex ] }\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Get the MT tool between two language pairs\n request:\n params:\n from: en\n to: es\n tool: mt\n response:\n status: 200\n headers:\n content-type: application/json\n # from routes/v2.js\n /v2/page/{sourcelanguage}/{targetlanguage}/{title}:\n get:\n tags:\n - Page content\n summary: Fetches segmented mediawiki page\n parameters:\n - $ref: \"#/components/parameters/sourcelanguage\"\n - $ref: \"#/components/parameters/targetlanguage\"\n - $ref: \"#/components/parameters/title\"\n responses:\n 200:\n description: Success\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Translate enwiki protected page\n request:\n params:\n sourcelanguage: en\n targetlanguage: es\n title: User:BSitzmann_(WMF)/MCS/Test/Frankenstein\n response:\n status: 200\n headers:\n content-type: application/json\n - title: Translate enwiki protected page with multi-word title\n request:\n params:\n sourcelanguage: en\n targetlanguage: es\n title: User:BSitzmann_(WMF)/MCS/Test/Frankenstein\n response:\n status: 200\n headers:\n content-type: application/json\n /v2/page/{sourcelanguage}/{targetlanguage}/{title}/{revision}:\n get:\n tags:\n - Page content\n summary: Fetches segmented mediawiki page with revision\n parameters:\n - $ref: \"#/components/parameters/sourcelanguage\"\n - $ref: \"#/components/parameters/targetlanguage\"\n - $ref: \"#/components/parameters/title\"\n - $ref: \"#/components/parameters/revision\"\n responses:\n 200:\n description: Success\n content:\n application/json:\n schema:\n type: object\n properties:\n sourceLanguage:\n type: string\n example: en\n title:\n type: string\n example: es\n revision:\n type: string\n example: 1234565\n segmentedContent:\n type: string\n example: lorem ipsum\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Translate enwiki protected page with revision\n request:\n params:\n sourcelanguage: en\n targetlanguage: es\n title: User:BSitzmann_(WMF)/MCS/Test/Frankenstein\n revision: 1086816359\n response:\n status: 200\n headers:\n content-type: application/json\n /v2/translate/{from}/{to}:\n post:\n tags:\n - Machine translation\n description: Adapt the content for the target language wiki without performing any machine translation.\n parameters:\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n requestBody:\n content:\n application/json:\n schema:\n required:\n - html\n properties:\n html:\n type: string\n examples:\n hello world:\n value: { html: <p>hello world</p> }\n required: true\n responses:\n 200:\n description: Success\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Machine translate an HTML fragment using TestClient, adapt the links to target language wiki.\n request:\n params:\n from: en\n to: qqq\n body:\n html: <p><a rel=\"mw:WikiLink\" href='./Oxygen' title='Oxygen'>Oxygen</a> is a chemical element with symbol O and <a rel=\"mw:WikiLink\" href='./Atomic number' title='Atomic number'>atomic number</a> 8.</p>\n response:\n status: 200\n body:\n contents: /.+/\n headers:\n content-type: application/json\n\n /v2/translate/{from}/{to}/{mtprovider}:\n post:\n tags:\n - Machine translation\n summary: Translate the given content from source language to target language.\n description: Also adapt the content for the target language wiki. Some machine translation\n providers require an authorization header and it is forbidden to use them outside the\n Content Translation tool.\n parameters:\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n - $ref: \"#/components/parameters/mtprovider\"\n requestBody:\n content:\n application/json:\n schema:\n required:\n - html\n properties:\n html:\n type: string\n examples:\n hello world:\n value: { html: <p>hello world</p> }\n required: true\n responses:\n 200:\n description: Success\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Machine translate an HTML fragment using TestClient, adapt the links to target language wiki.\n request:\n params:\n from: en\n to: qqq\n provider: TestClient\n body:\n html: <p><a rel=\"mw:WikiLink\" href='./Oxygen' title='Oxygen'>Oxygen</a> is a chemical element with symbol O and <a rel=\"mw:WikiLink\" href='./Atomic number' title='Atomic number'>atomic number</a> 8.</p>\n response:\n status: 200\n body:\n contents: /.+/\n headers:\n content-type: application/json\n /v2/suggest/title/{title}/{from}/{to}:\n get:\n tags:\n - Suggestions\n summary: Suggest a target title for the given source title and language pairs\n parameters:\n - $ref: \"#/components/parameters/title\"\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n responses:\n 200:\n description: Success\n content:\n application/json:\n schema:\n type: object\n properties:\n history:\n type: array\n items:\n type: string\n description: Suggested title\n example:\n items:\n - Histoire\n - Historique\n 403:\n description: Authentication error. The default MT provider for the given language pair\n needs authorization, and the given JWT is invalid.\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Suggest a target title for the given source title and language pairs\n description: The invalid JWT key is not used, as default MT provider doesn't need authentication\n request:\n headers:\n authorization: Test-auth\n params:\n title: Limonero\n from: es\n to: ca\n response:\n status: 200\n body:\n sourceLanguage: es\n targetLanguage: ca\n sourceTitle: Limonero\n targetTitle: llimoner\n headers:\n content-type: application/json\n - title: Return an authentication error HTTP status code, when default MT requires authentication and the given JWT is invalid\n description: The invalid JWT key is used, as default MT provider needs authentication\n request:\n headers:\n authorization: Test-auth\n params:\n title: Lemon\n from: en\n to: el\n response:\n status: 403\n /v2/suggest/source/{title}/{to}:\n get:\n tags:\n - Suggestions\n summary: Suggest a source article to use for creating given article in given target language\n using translation\n parameters:\n - $ref: \"#/components/parameters/title\"\n - $ref: \"#/components/parameters/to\"\n - $ref: \"#/components/parameters/sourcelanguages\"\n responses:\n 200:\n description: Success\n content:\n application/json:\n schema:\n type: object\n properties:\n suggestions:\n type: array\n items:\n type: object\n properties:\n pageId:\n type: integer\n example: 736\n ns:\n type: integer\n example: 0\n title:\n type: string\n example: Albert Einstein\n pageprops:\n type: object\n properties:\n wikibase_item:\n type: string\n example: Q937\n thumbnail:\n type: object\n properties:\n source:\n type: string\n example: https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Einstein_1921_by_F_Schmutzer_-_restoration.jpg/80px-Einstein_1921_by_F_Schmutzer_-_restoration.jpg\n width:\n type: integer\n example: 80\n height:\n type: integer\n example: 105\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Suggest a source title to use for translation\n request:\n params:\n to: ca\n title: Paneer\n query:\n sourcelanguages: en\n response:\n status: 200\n body:\n suggestions: /^\\[.+\\]$/\n headers:\n content-type: application/json\n /v2/suggest/sections/titles/{from}/{to}:\n get:\n tags:\n - Suggestions\n summary: Suggest target section titles based on provided source section titles. Titles are\n provided as URL params under the key \"titles\"\n parameters:\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n - $ref: \"#/components/parameters/titles\"\n responses:\n 200:\n description: Success\n content:\n application/json:\n schema:\n type: object\n properties:\n history:\n type: array\n items:\n type: string\n description: Suggested section title\n example:\n - Histoire\n - Historique\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Suggest target section titles for given source sections\n request:\n params:\n from: en\n to: es\n query:\n titles: References|Notes|External Links\n response:\n status: 200\n body:\n References: [ Referencias, Bibliografía ]\n Notes: [ Referencias, Notas ]\n External Links: [ Enlaces externos ]\n headers:\n content-type: application/json\n /v2/suggest/sections/{title}/{from}/{to}:\n get:\n tags:\n - Suggestions\n summary: Suggest sections to translate from a source article to its corresponding article\n in target language.\n parameters:\n - $ref: \"#/components/parameters/title\"\n - $ref: \"#/components/parameters/from\"\n - $ref: \"#/components/parameters/to\"\n responses:\n 200:\n description: Success\n content:\n application/json:\n schema:\n type: object\n properties:\n sections:\n type: object\n properties:\n sourceLanguage:\n type: string\n example: en\n sourceTitle:\n type: string\n example: Albert Einstein\n targetLanguage:\n type: string\n example: fr\n targetTitle:\n type: string\n example: Albert Einstein\n sourceSections:\n type: array\n items:\n type: string\n targetSections:\n type: array\n items:\n type: string\n present:\n type: object\n missing:\n type: object\n 404:\n description: Not Found\n 500:\n description: Server Error\n x-amples:\n - title: Suggest source sections to translate\n request:\n params:\n from: en\n to: ml\n title: Sitar\n response:\n status: 200\n body:\n sections:\n sourceLanguage: /.+/\n targetLanguage: /.+/\n sourceTitle: /.+/\n targetTitle: /.+/\n present: /.+/\n missing: /.+/\n headers:\n content-type: application/json\n\n # from routes/info.js\n /_info:\n get:\n tags:\n - Service information\n summary: Gets information about the service\n responses:\n 200:\n description: OK\n x-amples:\n - title: retrieve service info\n request: {}\n response:\n status: 200\n headers:\n content-type: application/json\n body:\n name: /.+/\n description: /.+/\n version: /.+/\n home: /.+/\n /_info/name:\n get:\n tags:\n - Service information\n - Service name\n summary: Gets the name of the service\n responses:\n 200:\n description: OK\n content:\n application/json:\n schema:\n type: object\n properties:\n name:\n type: string\n example: { name: cxserver }\n x-amples:\n - title: retrieve service name\n request: {}\n response:\n status: 200\n headers:\n content-type: application/json\n body:\n name: /.+/\n /_info/version:\n get:\n tags:\n - Service information\n - Service version\n summary: Gets the running version of the service\n responses:\n 200:\n description: OK\n content:\n application/json:\n schema:\n type: object\n properties:\n version:\n type: string\n example: { version: 1.2.1 }\n x-amples:\n - title: retrieve service version\n request: {}\n response:\n status: 200\n headers:\n content-type: application/json\n body:\n version: /.+/\n /_info/home:\n get:\n tags:\n - Service information\n - Service homepage\n summary: Redirects to the home page\n responses:\n 301:\n description: Redirect\n x-amples:\n - title: redirect to the home page\n request: {}\n response:\n status: 301\ncomponents:\n parameters:\n domain:\n in: path\n name: domain\n required: true\n schema:\n type: string\n description: |\n Project domain for the requested data.\n language:\n in: path\n name: language\n required: true\n schema:\n type: string\n examples:\n English:\n value: en\n Spanish:\n value: es\n description: |\n Valid language code\n revision:\n in: path\n name: revision\n required: true\n schema:\n type: string\n description: |\n Revision Id\n example:\n 1274260387:\n value: 1274260387\n title:\n in: path\n name: title\n required: true\n schema:\n type: string\n examples:\n Albert Einstein:\n value: Albert Einstein\n Roller Coaster:\n value: Roller coaster\n description: |\n Page title. Use underscores instead of spaces. Example: `Main_Page`\n spec:\n in: query\n name: spec\n required: false\n schema:\n type: string\n examples:\n spec:\n value: true\n doc:\n value: true\n fooo:\n value: true\n description: |\n Page title. Use underscores instead of spaces. Example: `Main_Page`\n prop:\n in: path\n name: prop\n required: true\n schema:\n type: string\n description: |\n Site info prop.\n from:\n name: from\n in: path\n description: The source language code\n examples:\n English:\n value: en\n Spanish:\n value: es\n schema:\n type: string\n required: true\n sourcelanguage:\n name: sourcelanguage\n in: path\n description: The source language code\n schema:\n type: string\n examples:\n English:\n value: en\n Spanish:\n value: es\n required: true\n to:\n name: to\n in: path\n description: The target language code\n schema:\n type: string\n examples:\n Spanish:\n value: es\n French:\n value: fr\n required: true\n targetlanguage:\n name: targetlanguage\n in: path\n description: The target language code\n schema:\n type: string\n examples:\n French:\n value: fr\n Spanish:\n value: es\n required: true\n titles:\n in: query\n name: titles\n description: List of source section titles separated by pipe (\"|\") delimiter, based\n on which target section suggestions will be given. Should be passed as array\n inside URL params (e.g. titles=test1|test2)\n schema:\n type: string\n required: true\n examples:\n History|Background:\n value: History|Background\n History:\n value: History\n Background:\n value: Background\n sourcelanguages:\n name: sourcelanguages\n in: query\n description: Comma-separated list of candidate source languages. By default English(en)\n is used as a source language unless that is the target language.\n schema:\n type: array\n items:\n type: string\n examples:\n en,es:\n value: en,es\n style: simple\n explode: true\n required: true\n word:\n name: word\n in: path\n description: The word to lookup\n schema:\n type: string\n required: true\n mtprovider:\n name: mtprovider\n in: path\n description: The machine translation provider id\n required: true\n schema:\n type: string\n enum:\n - MinT\n - Apertium\n examples:\n MinT:\n value: MinT\n tool:\n name: tool\n in: path\n description: The tool name\n schema:\n type: string\n enum:\n - mt\n examples:\n mt:\n value: mt\n required: true\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/adaptation/AdaptationTest.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":25,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":33}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { after, before, describe, it } from 'node:test';\nimport { deepEqual, equal, ok } from 'node:assert/strict';\nimport { each } from 'async';\nimport { JSDOM } from 'jsdom';\nimport Adapter from '../../lib/Adapter.js';\nimport MWApiRequestManager from '../../lib/mw/MWApiRequestManager.js';\nimport TestClient from '../../lib/mt/TestClient.js';\nimport TestUtils from '../testutils.js';\nimport { getConfig } from '../../lib/util.js';\nimport { initApp } from '../../app.js';\nimport mocks from './AdaptationTests.mocks.json' assert { type: 'json' };\nimport tests from './AdaptationTests.json' assert { type: 'json' };\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\ndescribe( 'Adaptation tests', () => {\n\tlet app, api, mocker;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t\tapi = new MWApiRequestManager( app );\n\t\tmocker = new TestUtils( api );\n\t\tmocker.setup( mocks );\n\t} );\n\n\tafter( () => {\n\t\tmocker.dump( dirname + '/AdaptationTests.mocks.json' );\n\t} );\n\n\teach( tests, ( testcase, done ) => {\n\t\tit( testcase.desc, () => {\n\n\t\t\tapp.mtClient = new TestClient( app );\n\t\t\tconst adapter = new Adapter( testcase.from, testcase.to, api, app );\n\n\t\t\treturn adapter.adapt( testcase.source ).then( ( result ) => {\n\t\t\t\tconst actualDom = new JSDOM( result.getHtml() );\n\n\t\t\t\tfor ( const id in testcase.resultAttributes ) {\n\t\t\t\t\tok( actualDom.window.document.getElementById( id ), `Element with id ${ id } exists in the result` );\n\t\t\t\t\tfor ( const attribute in testcase.resultAttributes[ id ] ) {\n\t\t\t\t\t\tconst actualAttributeValue = actualDom.window.document\n\t\t\t\t\t\t\t.getElementById( id ).getAttribute( attribute );\n\t\t\t\t\t\tconst expectedAttributeValue = testcase.resultAttributes[ id ][ attribute ];\n\t\t\t\t\t\tif ( attribute === 'text' ) {\n\t\t\t\t\t\t\tconst actualText = actualDom.window.document\n\t\t\t\t\t\t\t\t.getElementById( id ).textContent;\n\t\t\t\t\t\t\tequal(\n\t\t\t\t\t\t\t\tactualText,\n\t\t\t\t\t\t\t\ttestcase.resultAttributes[ id ][ attribute ],\n\t\t\t\t\t\t\t\t`Comparing text value for element ${ id }`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else if ( typeof expectedAttributeValue === 'object' ) {\n\t\t\t\t\t\t\tdeepEqual(\n\t\t\t\t\t\t\t\tJSON.parse( actualAttributeValue ),\n\t\t\t\t\t\t\t\texpectedAttributeValue,\n\t\t\t\t\t\t\t\t`Comparing attribute ${ attribute } for element ${ id }`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeepEqual(\n\t\t\t\t\t\t\t\tactualAttributeValue,\n\t\t\t\t\t\t\t\texpectedAttributeValue,\n\t\t\t\t\t\t\t\t`Comparing attribute ${ attribute } for element ${ id }`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdone( null );\n\t\t\t} );\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/adaptation/AdaptationTests.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/adaptation/AdaptationTests.mocks.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/adaptation/SectionTest.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":18,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":26},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":31,"column":20,"nodeType":"CallExpression","endLine":31,"endColumn":80}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { before, describe, it } from 'node:test';\nimport { readFileSync } from 'fs';\nimport { deepEqual } from 'node:assert/strict';\nimport { JSDOM } from 'jsdom';\nimport Adapter from '../../lib/Adapter.js';\nimport MWApiRequestManager from '../../lib/mw/MWApiRequestManager.js';\nimport { TestClient } from '../../lib/mt/index.js';\nimport { getConfig } from '../../lib/util.js';\nimport { initApp } from '../../app.js';\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\nconst testcase = {\n\tdesc: 'section has lot of templates, but all are fragments of main template',\n\tfrom: 'en',\n\tto: 'es',\n\tsource: 'section-1.html',\n\tadaptationCount: 1\n};\n\ndescribe( 'Adaptation tests', () => {\n\tlet app;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t} );\n\n\tit( 'should adapt section when: ' + testcase.desc, async () => {\n\t\tconst api = new MWApiRequestManager( app );\n\t\tapp.mtClient = new TestClient( app );\n\t\tconst adapter = new Adapter( testcase.from, testcase.to, api, app );\n\t\tconst testData = readFileSync( dirname + '/data/' + testcase.source, 'utf8' );\n\t\tconst result = await adapter.adapt( testData );\n\t\tconst resultDom = new JSDOM( result.getHtml() );\n\t\tconst elementWithDataCX = resultDom.window.document.querySelectorAll( '[data-cx]' );\n\t\tdeepEqual( elementWithDataCX.length, testcase.adaptationCount );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/adaptation/TemplateParameterMapper.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[{"ruleId":"camelcase","severity":2,"message":"Identifier 'name_with_a_tailing_space' is not in camel case.","line":48,"column":4,"nodeType":"Identifier","messageId":"notCamelCase","endLine":48,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport TemplateParameterMapper from '../../lib/adaptation/TemplateParameterMapper.js';\nimport { deepEqual } from '../utils/assert.js';\n\nconst test = {\n\tsourceParams: {\n\t\t0: { wt: 'FirstValue' },\n\t\tsrcName: { wt: 'NameValue' },\n\t\tfirstname: { wt: 'FirstNameValue' },\n\t\t'namewithatailingspace ': { wt: 'SomeValue' },\n\t\tauthor: { wt: 'AuthorName' },\n\t\t'author-link1': { wt: 'author-link1-value' },\n\t\tdatum: { wt: '25/12/2018' }\n\t},\n\tsourceTemplateData: {\n\t\tmaps: {\n\t\t\tcitoid: {\n\t\t\t\tdate: 'Datum'\n\t\t\t}\n\t\t},\n\t\tparams: {\n\t\t\tname: {\n\t\t\t\taliases: [ 'srcName' ]\n\t\t\t},\n\t\t\tfirstname: { aliases: [ 'first-name' ] },\n\t\t\t'namewithatailingspace ': {},\n\t\t\tauthor: { aliases: [ 'writer' ] },\n\t\t\t'author-link1': { aliases: [ 'authorlink' ] },\n\t\t\tdatum: {},\n\t\t\ttitel: {}\n\t\t}\n\t},\n\ttargetTemplateData: {\n\t\tmaps: {\n\t\t\tcitoid: {\n\t\t\t\tedition: 'edition',\n\t\t\t\tpublicationTitle: 'title'\n\t\t\t}\n\t\t},\n\t\tparams: {\n\t\t\ttítulo: {\n\t\t\t\taliases: [ 'Name', 'nombre' ]\n\t\t\t},\n\t\t\t'primero-título': {\n\t\t\t\taliases: [ 'First_Name', 'naciente' ]\n\t\t\t},\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tname_with_a_tailing_space: {},\n\t\t\tescritor: {\n\t\t\t\taliases: [ 'Writer' ]\n\t\t\t},\n\t\t\t'escritor-link': {\n\t\t\t\taliases: [ 'authorlink' ]\n\t\t\t},\n\t\t\tdate: {}\n\t\t}\n\t},\n\texpectedParamMapping: {\n\t\t// Unnamed param name\n\t\t0: '0',\n\t\t// Mapped by aliases of source and target\n\t\tsrcName: 'título',\n\t\t// Mapped by aliases of target\n\t\tfirstname: 'primero-título',\n\t\t// Normalized source name, target name match\n\t\t'namewithatailingspace ': 'name_with_a_tailing_space',\n\t\t// Mapped by aliases of source and target\n\t\tauthor: 'escritor',\n\t\t// Mapped by aliases of source and target\n\t\t'author-link1': 'escritor-link',\n\t\tdatum: 'date'\n\t}\n};\ndescribe( 'Template parameter mapping test', () => {\n\tconst mapper = new TemplateParameterMapper(\n\t\ttest.sourceParams, test.sourceTemplateData, test.targetTemplateData\n\t);\n\tit( 'should not have any errors while mapping params', () => {\n\t\tdeepEqual( mapper.getParameterMap(), ( test.expectedParamMapping ) );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/app/app.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":18,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":26}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { before, describe, it } from 'node:test';\nimport request from 'supertest';\nimport { deepEqual } from '../../utils/assert.js';\nimport { getConfig } from '../../../lib/util.js';\nimport { initApp } from '../../../app.js';\n\ndescribe( 'express app', async () => {\n\tlet app;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t} );\n\n\tit( 'should get robots.txt', async () => {\n\t\tconst response = await request( app ).get( '/robots.txt' );\n\t\tdeepEqual( response.text, 'User-agent: *\\nDisallow: /' );\n\t\tdeepEqual( response.statusCode, 200 );\n\t} );\n\n\tit( 'should set CORS headers', async () => {\n\t\tif ( getConfig().cors === false ) {\n\t\t\treturn true;\n\t\t}\n\t\tconst response = await request( app ).get( '/robots.txt' );\n\t\tdeepEqual( response.headers[ 'access-control-allow-origin' ], '*' );\n\t\tdeepEqual( !!( response.headers[ 'access-control-allow-headers' ] ), true );\n\t\tdeepEqual( !!( response.headers[ 'access-control-expose-headers' ] ), true );\n\t\tdeepEqual( response.statusCode, 200 );\n\n\t} );\n\n\tit( 'should set CSP headers', async () => {\n\t\tif ( getConfig().csp === false ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst response = await request( app ).get( '/robots.txt' );\n\t\tdeepEqual( response.headers[ 'x-xss-protection' ], '1; mode=block' );\n\t\tdeepEqual( response.headers[ 'x-content-type-options' ], 'nosniff' );\n\t\tdeepEqual( response.headers[ 'x-frame-options' ], 'SAMEORIGIN' );\n\t\tdeepEqual( response.headers[ 'content-security-policy' ], 'default-src' );\n\t\tdeepEqual( response.headers[ 'x-content-security-policy' ], 'default-src' );\n\t\tdeepEqual( response.headers[ 'x-webkit-csp' ], 'default-src' );\n\n\t} );\n\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/app/spec.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":18,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":26},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":21,"column":16,"nodeType":"CallExpression","endLine":21,"endColumn":40},{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":168,"column":10,"nodeType":"NewExpression","endLine":168,"endColumn":47}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { before, describe, it } from 'node:test';\nimport { readFileSync } from 'fs';\nimport swaggerrouter from 'swagger-router';\nimport { load } from 'js-yaml';\nimport request from 'supertest';\nimport OpenAPISchemaValidator from 'openapi-schema-validator';\nimport { status as assertStatus, contentType, deepEqual, notDeepEqual } from '../../utils/assert.js';\nimport { getConfig } from '../../../lib/util.js';\nimport { initApp } from '../../../app.js';\n\nconst ValidatorClass = OpenAPISchemaValidator.default;\nconst validator = new ValidatorClass( { version: 3 } );\nconst dirname = new URL( '.', import.meta.url ).pathname;\nfunction staticSpecLoad() {\n\n\tlet spec;\n\tconst myService = getConfig();\n\tconst specPath = `${ dirname }/../../../${ myService.spec ? myService.spec : 'spec.yaml' }`;\n\n\ttry {\n\t\tspec = load( readFileSync( specPath ) );\n\t} catch ( e ) {\n\t\tthrow new Error( `Cannot load spec file: ${ specPath }` );\n\t}\n\n\treturn spec;\n\n}\n\nfunction validateExamples( pathStr, defParams, mSpec ) {\n\n\tconst uri = new swaggerrouter.URI( pathStr, {}, true );\n\n\tif ( !mSpec ) {\n\t\ttry {\n\t\t\turi.expand( defParams );\n\t\t\treturn true;\n\t\t} catch ( e ) {\n\t\t\tthrow new Error( `Missing parameter for route ${ pathStr } : ${ e.message }` );\n\t\t}\n\t}\n\n\tif ( !Array.isArray( mSpec ) ) {\n\t\tthrow new Error( `Route ${ pathStr } : x-amples must be an array!` );\n\t}\n\n\tmSpec.forEach( ( ex, idx ) => {\n\t\tif ( !ex.title ) {\n\t\t\tthrow new Error( `Route ${ pathStr }, example ${ idx }: title missing!` );\n\t\t}\n\t\tex.request = ex.request || {};\n\t\ttry {\n\t\t\turi.expand( Object.assign( {}, defParams, ex.request.params || {} ) );\n\t\t} catch ( e ) {\n\t\t\tthrow new Error(\n\t\t\t\t`Route ${ pathStr }, example ${ idx } (${ ex.title }): missing parameter: ${ e.message }`\n\t\t\t);\n\t\t}\n\t} );\n\n\treturn true;\n\n}\n\nfunction constructTestCase( title, path, method, req, response ) {\n\n\treturn {\n\t\ttitle,\n\t\trequest: {\n\t\t\turi: '/' + ( path[ 0 ] === '/' ? path.slice( 1 ) : path ),\n\t\t\tmethod,\n\t\t\theaders: req.headers || { 'Content-Type': 'application/json' },\n\t\t\tquery: req.query,\n\t\t\tbody: req.body,\n\t\t\tfollowRedirect: false\n\t\t},\n\t\tresponse: {\n\t\t\tstatus: response.status || 200,\n\t\t\theaders: response.headers || {},\n\t\t\tbody: response.body\n\t\t}\n\t};\n\n}\n\nfunction constructTests( paths, defParams ) {\n\n\tconst ret = [];\n\n\tObject.keys( paths ).forEach( ( pathStr ) => {\n\t\tObject.keys( paths[ pathStr ] ).forEach( ( method ) => {\n\t\t\tconst p = paths[ pathStr ][ method ];\n\t\t\tif ( {}.hasOwnProperty.call( p, 'x-monitor' ) && !p[ 'x-monitor' ] ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst uri = new swaggerrouter.URI( pathStr, {}, true );\n\t\t\tif ( !p[ 'x-amples' ] ) {\n\t\t\t\tret.push( constructTestCase(\n\t\t\t\t\tpathStr,\n\t\t\t\t\turi.toString( { params: defParams } ),\n\t\t\t\t\tmethod,\n\t\t\t\t\t{},\n\t\t\t\t\t{}\n\t\t\t\t) );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tp[ 'x-amples' ].forEach( ( ex ) => {\n\t\t\t\tex.request = ex.request || {};\n\t\t\t\tret.push( constructTestCase(\n\t\t\t\t\tex.title,\n\t\t\t\t\turi.toString( {\n\t\t\t\t\t\tparams: Object.assign( {}, defParams, ex.request.params || {} )\n\t\t\t\t\t} ),\n\t\t\t\t\tmethod,\n\t\t\t\t\tex.request,\n\t\t\t\t\tex.response || {}\n\t\t\t\t) );\n\t\t\t} );\n\t\t} );\n\t} );\n\n\treturn ret;\n\n}\n\nfunction cmp( result, expected, errMsg ) {\n\n\tif ( expected === null || expected === undefined ) {\n\t\t// nothing to expect, so we can return\n\t\treturn true;\n\t}\n\tif ( result === null || result === undefined ) {\n\t\tresult = '';\n\t}\n\n\tif ( expected.constructor === Object ) {\n\t\tObject.keys( expected ).forEach( ( key ) => {\n\t\t\tconst val = expected[ key ];\n\t\t\tdeepEqual( {}.hasOwnProperty.call( result, key ), true,\n\t\t\t\t`Body field ${ key } not found in response!` );\n\t\t\tcmp( result[ key ], val, `${ key } body field mismatch!` );\n\t\t} );\n\t\treturn true;\n\t} else if ( expected.constructor === Array ) {\n\t\tif ( result.constructor !== Array ) {\n\t\t\tdeepEqual( result, expected, errMsg );\n\t\t\treturn true;\n\t\t}\n\t\t// only one item in expected - compare them all\n\t\tif ( expected.length === 1 && result.length > 1 ) {\n\t\t\tresult.forEach( ( item ) => {\n\t\t\t\tcmp( item, expected[ 0 ], errMsg );\n\t\t\t} );\n\t\t\treturn true;\n\t\t}\n\t\t// more than one item expected, check them one by one\n\t\tif ( expected.length !== result.length ) {\n\t\t\tdeepEqual( result, expected, errMsg );\n\t\t\treturn true;\n\t\t}\n\t\texpected.forEach( ( item, idx ) => {\n\t\t\tcmp( result[ idx ], item, errMsg );\n\t\t} );\n\t\treturn true;\n\t}\n\n\tif ( expected.length > 1 && expected[ 0 ] === '/' && expected[ expected.length - 1 ] === '/' ) {\n\t\tif ( ( new RegExp( expected.slice( 1, -1 ) ) ).test( result ) ) {\n\t\t\treturn true;\n\t\t}\n\t} else if ( expected.length === 0 && result.length === 0 ) {\n\t\treturn true;\n\t} else if ( result === expected || result.startsWith( expected ) ) {\n\t\treturn true;\n\t}\n\n\tdeepEqual( result, expected, errMsg );\n\treturn true;\n\n}\n\nasync function validateTestResponse( testCase, response ) {\n\n\tconst expRes = testCase.response;\n\tif ( response.statusCode === 500 ) {\n\t\tconsole.error( response );\n\t}\n\t// check the status\n\tdeepEqual( response.statusCode, expRes.status, 'Status mismatch!' );\n\n\t// check the headers\n\tObject.keys( expRes.headers ).forEach( ( key ) => {\n\t\tconst val = expRes.headers[ key ];\n\t\tdeepEqual( !!response.headers[ key ], true,\n\t\t\t`Header ${ key } not found in response!` );\n\t\tcmp( response.headers[ key ], val, `${ key } header mismatch!` );\n\t} );\n\n\t// check the body\n\tif ( !expRes.body ) {\n\t\treturn true;\n\t}\n\tlet body = await response.body || '';\n\tif ( Buffer.isBuffer( body ) ) {\n\t\tbody = body.toString();\n\t}\n\tif ( expRes.body.constructor !== body.constructor ) {\n\t\tif ( expRes.body.constructor === String ) {\n\t\t\tbody = JSON.stringify( body );\n\t\t} else {\n\t\t\tbody = JSON.parse( body );\n\t\t}\n\t}\n\t// check that the body type is the same\n\tif ( expRes.body.constructor !== body.constructor ) {\n\t\tthrow new Error(\n\t\t\t`Expected body type ${ expRes.body.constructor } but got ${ body.constructor }`\n\t\t);\n\t}\n\n\t// compare the bodies\n\tcmp( body, expRes.body, 'Body mismatch!' );\n\n\treturn true;\n\n}\n\ndescribe( 'Swagger spec', async () => {\n\tlet app;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t} );\n\n\t// the variable holding the spec\n\tlet spec = staticSpecLoad();\n\t// default params, if given\n\tlet defParams = spec[ 'x-default-params' ] || {};\n\n\tit( 'get the spec', async () => {\n\t\tconst response = await request( app ).get( '?spec' );\n\n\t\tconst data = await response.body;\n\t\tassertStatus( response, 200 );\n\t\tcontentType( response, 'application/json; charset=utf-8' );\n\t\tnotDeepEqual( data, undefined, 'No body received!' );\n\t\tspec = data;\n\t} );\n\n\tit( 'should expose valid OpenAPI spec', async () => {\n\t\tconst response = await request( app ).get( '?spec' );\n\t\tconst data = await response.body;\n\t\tdeepEqual( { errors: [] }, validator.validate( data ), 'Spec must have no validation errors' );\n\n\t} );\n\n\tit( 'spec validation', () => {\n\t\tif ( spec[ 'x-default-params' ] ) {\n\t\t\tdefParams = spec[ 'x-default-params' ];\n\t\t}\n\t\t// check the high-level attributes\n\t\t[ 'info', 'openapi', 'paths' ].forEach( ( prop ) => {\n\t\t\tdeepEqual( !!spec[ prop ], true, `No ${ prop } field present!` );\n\t\t} );\n\t\t// no paths - no love\n\t\tdeepEqual( !!Object.keys( spec.paths ), true, 'No paths given in the spec!' );\n\t\t// now check each path\n\t\tObject.keys( spec.paths ).forEach( ( pathStr ) => {\n\t\t\tdeepEqual( !!pathStr, true, 'A path cannot have a length of zero!' );\n\t\t\tconst path = spec.paths[ pathStr ];\n\t\t\tdeepEqual( !!Object.keys( path ), true, `No methods defined for path: ${ pathStr }` );\n\t\t\tObject.keys( path ).forEach( ( method ) => {\n\t\t\t\tconst mSpec = path[ method ];\n\t\t\t\tif ( {}.hasOwnProperty.call( mSpec, 'x-monitor' ) && !mSpec[ 'x-monitor' ] ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvalidateExamples( pathStr, defParams, mSpec[ 'x-amples' ] );\n\t\t\t} );\n\t\t} );\n\t} );\n\n\tdescribe( 'routes', async () => {\n\t\tconstructTests( spec.paths, defParams ).forEach( ( testCase ) => {\n\t\t\tit( testCase.title, async () => {\n\t\t\t\tlet uri = testCase.request.uri;\n\t\t\t\tlet response;\n\t\t\t\tconst options = {\n\t\t\t\t\tmethod: testCase.request.method.toUpperCase(),\n\t\t\t\t\theaders: testCase.request.headers,\n\t\t\t\t\tredirect: 'manual'\n\t\t\t\t};\n\t\t\t\tif ( options.method === 'POST' && testCase.request.body ) {\n\t\t\t\t\toptions.body = JSON.stringify( testCase.request.body );\n\n\t\t\t\t\tresponse = await request( app ).post( uri ).send( options.body ).set( 'Content-Type', 'application/json' )\n\t\t\t\t\t\t.set( 'Accept', 'application/json' );\n\t\t\t\t} else {\n\t\t\t\t\turi = `${ uri }?${ new URLSearchParams( testCase.request.query ).toString() }`;\n\t\t\t\t\tresponse = await request( app ).get( uri, options );\n\t\t\t\t}\n\n\t\t\t\tconst result = await validateTestResponse( testCase, response );\n\n\t\t\t\treturn result;\n\t\t\t} );\n\t\t} );\n\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/info/info.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":18,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":26}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { before, describe, it } from 'node:test';\nimport request from 'supertest';\nimport { contentType, deepEqual, notDeepEqual, status } from '../../utils/assert.js';\nimport { getConfig } from '../../../lib/util.js';\nimport { initApp } from '../../../app.js';\n\ndescribe( 'service information', async () => {\n\tlet app;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t} );\n\n\t// common URI prefix for info tests\n\tconst infoUri = '/_info/';\n\n\t// common function used for generating requests\n\t// and checking their return values\n\tasync function checkRet( fieldName ) {\n\t\tconst response = await request( app ).get( infoUri + fieldName );\n\t\tconst data = await response.body;\n\t\t// check the returned Content-Type header\n\t\tdeepEqual( response.headers[ 'content-type' ], 'application/json; charset=utf-8' );\n\n\t\t// the status as well\n\t\tdeepEqual( response.statusCode, 200 );\n\t\t// finally, check the body has the specified field\n\t\tnotDeepEqual( data, undefined, 'No body returned!' );\n\t\tnotDeepEqual( data[ fieldName ], undefined, `No ${ fieldName } field returned!` );\n\t}\n\n\tit( 'should get the service name', () => checkRet( 'name' ) );\n\n\tit( 'should get the service version', () => checkRet( 'version' ) );\n\n\tit( 'should redirect to the service home page', async () => {\n\t\tconst response = await request( app ).get( `${ infoUri }home`, { redirect: 'manual' } );\n\t\tstatus( response, 301 );\n\t} );\n\n\tit( 'should get the service info', async () => {\n\t\tconst response = await request( app ).get( infoUri );\n\t\tconst data = await response.body;\n\t\t// check the status\n\t\tdeepEqual( response.statusCode, 200 );\n\t\t// check the returned Content-Type header\n\t\tcontentType( response, 'application/json; charset=utf-8' );\n\t\t// inspect the body\n\t\tnotDeepEqual( data, undefined, 'No body returned!' );\n\t\tnotDeepEqual( data.name, undefined, 'No name field returned!' );\n\t\tnotDeepEqual( data.version, undefined, 'No version field returned!' );\n\t\tnotDeepEqual( data.description, undefined, 'No description field returned!' );\n\t\tnotDeepEqual( data.home, undefined, 'No home field returned!' );\n\t} );\n\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/v1/page.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":18,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":26}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { before, describe, it } from 'node:test';\nimport assert from 'node:assert/strict';\nimport request from 'supertest';\nimport { contentType, deepEqual, notDeepEqual } from '../../utils/assert.js';\nimport { getConfig } from '../../../lib/util.js';\nimport { initApp } from '../../../app.js';\n\ndescribe( 'v1 api - page gets', async () => {\n\tlet app;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t} );\n\n\t// common URI prefix for the page\n\tconst uri = '/v1/page/en/Oxygen';\n\n\tit( 'should get the whole page body', async () => {\n\t\tconst response = await request( app ).get( uri );\n\n\t\tconst data = await response.body;\n\t\t// check the status\n\t\tdeepEqual( response.statusCode, 200 );\n\t\t// check the returned Content-Type header\n\t\tcontentType( response, 'application/json; charset=utf-8' );\n\t\t// inspect the body\n\t\tnotDeepEqual( data, undefined, 'No body returned!' );\n\t\t// this should be the right page\n\t\tdeepEqual( data.title, 'Oxygen', 'Got the correct title' );\n\t\t// Must have revision id\n\t\tassert.ok( +data.revision >= 683049648 );\n\n\t} );\n\n\tit( 'should throw a 404 for a non-existent page', async () => {\n\t\tconst url = '/v1/page/Wikipedia_content_translation_system';\n\t\tconst response = await request( app ).get( url );\n\t\tdeepEqual( response.statusCode, 404 );\n\t} );\n\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/v2/page.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":18,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":26}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { before, describe, it } from 'node:test';\nimport assert from 'node:assert/strict';\nimport request from 'supertest';\nimport { contentType, deepEqual, notDeepEqual } from '../../utils/assert.js';\nimport { initApp } from '../../../app.js';\nimport { getConfig } from '../../../lib/util.js';\n\ndescribe( 'v2 api - page gets', () => {\n\tlet app;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t} );\n\n\t// common URI prefix for the page\n\tconst uri = '/v2/page/en/es/Pickling';\n\n\tit( 'should get the whole page body', async () => {\n\t\tconst response = await request( app ).get( uri );\n\t\tconst data = await response.body;\n\n\t\t// check the status\n\t\tdeepEqual( response.statusCode, 200 );\n\t\t// check the returned Content-Type header\n\t\tcontentType( response, 'application/json; charset=utf-8' );\n\t\t// inspect the body\n\t\tnotDeepEqual( data, undefined, 'No body returned!' );\n\t\t// this should be the right page\n\t\tdeepEqual( data.title, 'Pickling', 'Got the correct title' );\n\t\t// Must have revision id\n\t\tassert.ok( +data.revision >= 683049648 );\n\t\t// Must have segmented content\n\t\tassert.ok( +data.segmentedContent.length >= 100 );\n\t\t// Must have adapted categories\n\t\tassert.ok( +data.categories.length >= 1 );\n\t} );\n\n\tit( 'should throw a 404 for a non-existent page', async () => {\n\t\tconst url = '/v2/page/en/es/Wikipedia_content_translation_system';\n\t\tconst response = await request( app ).get( url );\n\t\tdeepEqual( response.statusCode, 404 );\n\t} );\n\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/lineardoc/LinearDoc.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":24,"column":22,"nodeType":"CallExpression","endLine":24,"endColumn":59},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":25,"column":24,"nodeType":"CallExpression","endLine":25,"endColumn":61},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":26,"column":26,"nodeType":"CallExpression","endLine":26,"endColumn":65},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":70,"column":28,"nodeType":"CallExpression","endLine":70,"endColumn":65},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":86,"column":28,"nodeType":"CallExpression","endLine":86,"endColumn":65},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":134,"column":27,"nodeType":"CallExpression","endLine":134,"endColumn":75},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":204,"column":28,"nodeType":"CallExpression","endLine":204,"endColumn":65}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":8,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { readFileSync } from 'fs';\nimport assert from 'node:assert/strict';\nimport { deepEqual } from '../utils/assert.js';\nimport { MwContextualizer, Normalizer, Parser } from '../../lib/lineardoc/index.js';\nimport { isIgnorableBlock } from '../../lib/lineardoc/Utils.js';\nimport transTests from './translate.test.json' assert { type: 'json' };\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\nfunction normalize( html ) {\n\tconst normalizer = new Normalizer();\n\tnormalizer.init();\n\tnormalizer.write( html.replace( /(\\r\\n|\\n|\\t|\\r)/gm, '' ) );\n\treturn normalizer.getHtml();\n}\n\ndescribe( 'LinearDoc', () => {\n\tit( 'should be possible to linearise all kind of HTML inputs', () => {\n\t\tconst numTests = 8;\n\t\tfor ( let i = 1; i <= numTests; i++ ) {\n\t\t\tconst testXhtmlFile = dirname + '/data/test' + i + '.xhtml';\n\t\t\tconst resultXmlFile = dirname + '/data/test' + i + '-result.xml';\n\t\t\tconst resultXhtmlFile = dirname + '/data/test' + i + '-result.xhtml';\n\t\t\tconst testXhtml = readFileSync( testXhtmlFile, 'utf8' ).replace( /^\\s+|\\s+$/, '' );\n\t\t\tconst expectedXml = readFileSync( resultXmlFile, 'utf8' ).replace( /^\\s+|\\s+$/, '' );\n\t\t\tconst expectedXhtml = readFileSync( resultXhtmlFile, 'utf8' ).replace( /^\\s+|\\s+$/, '' );\n\t\t\tconst parser = new Parser( new MwContextualizer() );\n\t\t\tparser.init();\n\t\t\tparser.write( testXhtml );\n\t\t\tassert.ok( !isIgnorableBlock( parser.builder.doc ), 'Not a section with block template' );\n\t\t\tdeepEqual(\n\t\t\t\tnormalize( parser.builder.doc.dumpXml() ),\n\t\t\t\tnormalize( expectedXml ),\n\t\t\t\t'Linearised structure'\n\t\t\t);\n\t\t\tdeepEqual(\n\t\t\t\tnormalize( parser.builder.doc.getHtml() ),\n\t\t\t\tnormalize( expectedXhtml ),\n\t\t\t\t'Reconstructed XHTML'\n\t\t\t);\n\t\t}\n\t} );\n\n\tit( 'should be possible to reconstruct the HTML from LinearDoc', () => {\n\t\tfor ( let i = 0, len = transTests.length; i < len; i++ ) {\n\t\t\tconst test = transTests[ i ];\n\t\t\tconst parser = new Parser( new MwContextualizer() );\n\t\t\tparser.init();\n\t\t\tparser.write( '<div>' + test.source + '</div>' );\n\t\t\tconst textBlock1 = parser.builder.doc.items[ 1 ].item;\n\t\t\tdeepEqual(\n\t\t\t\ttextBlock1.getHtml(),\n\t\t\t\ttest.source,\n\t\t\t\t'Reconstructed source HTML'\n\t\t\t);\n\t\t\tconst textBlock2 = textBlock1.translateTags(\n\t\t\t\ttest.targetText,\n\t\t\t\ttest.rangeMappings\n\t\t\t);\n\t\t\tdeepEqual(\n\t\t\t\ttextBlock2.getHtml(),\n\t\t\t\ttest.expect,\n\t\t\t\t'Translated HTML'\n\t\t\t);\n\t\t}\n\t} );\n\n\tit( 'should be possible to reduce and expand a document', () => {\n\t\tconst testXhtmlFile = dirname + '/data/test-figure-inline.html';\n\t\tconst contentForReduce = readFileSync( testXhtmlFile, 'utf8' ).replace( /^\\s+|\\s+$/, '' );\n\t\tconst parser = new Parser( new MwContextualizer() );\n\t\tparser.init();\n\t\tparser.write( contentForReduce );\n\t\tconst { reducedDoc, extractedData } = parser.builder.doc.reduce();\n\t\tdeepEqual( Object.keys( extractedData ).length, 16, 'Attributes for 16 tags extracted.' );\n\t\tconst expandedDoc = reducedDoc.expand( extractedData );\n\t\tdeepEqual(\n\t\t\tnormalize( expandedDoc.getHtml() ),\n\t\t\tnormalize( contentForReduce ),\n\t\t\t'Restored the original html after reduce and expand.'\n\t\t);\n\t} );\n\n\tit( 'test HTML compaction roundtrip with inline chunks', () => {\n\t\tconst testXhtmlFile = dirname + '/data/test-chunks-inline.html';\n\t\tconst contentForReduce = readFileSync( testXhtmlFile, 'utf8' ).replace( /^\\s+|\\s+$/, '' );\n\t\tconst parser = new Parser( new MwContextualizer() );\n\t\tparser.init();\n\t\tparser.write( contentForReduce );\n\t\tconst { reducedDoc, extractedData } = parser.builder.doc.reduce();\n\t\tdeepEqual( Object.keys( extractedData ).length, 22, 'Attributes for 22 tags extracted.' );\n\t\tconst expandedDoc = reducedDoc.expand( extractedData );\n\t\tdeepEqual(\n\t\t\tnormalize( expandedDoc.getHtml() ),\n\t\t\tnormalize( contentForReduce ),\n\t\t\t'Restored the original html after reduce and expand.'\n\t\t);\n\t} );\n\n\tit( 'test HTML expand with external attributes inserted', () => {\n\t\tconst corruptedDoc = `<p id=\"1\">\n\t\t\t<b id=\"2\" onclick=\"doSomething();\">Externally inserted attribute.</b>\n\t\t\t<a href=\"navigateThere();\">Externally inserted tag</a>\n\t\t\t<span id=\"mwEz\">Element with only id attribute is fine.</span>\n\t\t\t</p>`;\n\t\tconst sanitizedExpandedDoc = `<p class=\"paragraph\" id=\"mwEq\">\n\t\t\t<b class=\"bold\" id=\"mwEs\">Externally inserted attribute.</b>\n\t\t\t<a>Externally inserted tag</a>\n\t\t\t<span id=\"mwEz\">Element with only id attribute is fine.</span>\n\t\t\t</p>`;\n\t\tconst extractedData = {\n\t\t\t1: { attributes: { id: 'mwEq', class: 'paragraph' } },\n\t\t\t2: { attributes: { id: 'mwEs', class: 'bold' } }\n\t\t};\n\t\tconst parser = new Parser( new MwContextualizer() );\n\t\tparser.init();\n\t\tparser.write( corruptedDoc );\n\t\tconst expandedDoc = parser.builder.doc.expand( extractedData );\n\t\tdeepEqual(\n\t\t\tnormalize( expandedDoc.getHtml() ),\n\t\t\tnormalize( sanitizedExpandedDoc ),\n\t\t\t'Expanded the corrupted document by removing all externally inserted attributes.'\n\t\t);\n\t} );\n\n\tit( 'test if the content is block level template', () => {\n\t\tconst testFiles = [\n\t\t\t'/data/test-block-template-section-1.html',\n\t\t\t'/data/test-block-template-section-2.html',\n\t\t\t'/data/test-block-template-section-3.html',\n\t\t\t'/data/test-block-template-section-4.html'\n\t\t];\n\t\tfor ( let i = 0; i < testFiles.length; i++ ) {\n\t\t\tconst contentForTest = readFileSync( dirname + testFiles[ i ], 'utf8' ).replace( /^\\s+|\\s+$/, '' );\n\t\t\tconst parser = new Parser( new MwContextualizer() );\n\t\t\tparser.init();\n\t\t\tparser.write( contentForTest );\n\t\t\tassert.ok( isIgnorableBlock( parser.builder.doc ), `File ${ testFiles[ i ] } is section with block template` );\n\t\t}\n\t} );\n\n\tit( 'test HTML compaction roundtrip with inline style content', () => {\n\t\tconst sourceDoc = `<section><p>\n\t\t<a href=\"Our title\">ABC</a>\n\t\t<style> a { background: url(https://en.wikipedia.org/css-background); } </style>\n\t\t<script>original script</script>\n\t\t<script type=\"module\" src=\"main.js\"></script>\n\t\t<span id=\"mwKJ\" typeof=\"mw:Entity\">–</span>\n\t\t</p>\n\t\t</section>`;\n\n\t\tconst expectedReducedDoc = `<section><p>\n\t\t<a id=\"1\">ABC</a>\n\t\t<style id=\"2\"></style>\n\t\t<script id=\"3\"></script>\n\t\t<script id=\"4\"></script>\n\t\t<span id=\"5\">–</span>\n\t\t</p>\n\t\t</section>`;\n\t\t// MT result from external MT service. Assuming that it altered the style and script content.\n\t\tconst corruptedMTInput = `<section><p>\n\t\t<a id=\"1\" href=\"Their title\">abc</a>\n\t\t<style id=\"2\"> a { background: url(https://leaking.via/css-background); } </style>\n\t\t<script id=\"3\">Corrupted script</script>\n\t\t<script id=\"4\" src=\"https://bad.via/main.js\"></script>\n\t\t<span id=\"5\">©</span>\n\t\t</p>\n\t\t</section>`;\n\t\t// Expected final output after fixing all external modification\n\t\tconst sanitizedExpandedDoc = `<section><p>\n\t\t<a href=\"Our title\">abc</a>\n\t\t<style> a { background: url(https://en.wikipedia.org/css-background); } </style>\n\t\t<script>original script</script>\n\t\t<script type=\"module\" src=\"main.js\"></script>\n\t\t<span id=\"mwKJ\" typeof=\"mw:Entity\">–</span>\n\t\t</p>\n\t\t</section>`;\n\t\tlet parser = new Parser( new MwContextualizer() );\n\t\tparser.init();\n\t\tparser.write( sourceDoc );\n\t\tconst { reducedDoc, extractedData } = parser.builder.doc.reduce();\n\t\tdeepEqual(\n\t\t\tnormalize( reducedDoc.getHtml() ),\n\t\t\tnormalize( expectedReducedDoc ),\n\t\t\t'Expanded the corrupted document by removing all externally inserted attributes.'\n\t\t);\n\t\tdeepEqual( Object.keys( extractedData ).length, 5, 'Attributes for 2 tags extracted.' );\n\t\tdeepEqual( !!extractedData[ '2' ].content, true, 'Content extracted for style tag' );\n\t\tdeepEqual( !!extractedData[ '3' ].content, true, 'Content extracted for script tag' );\n\t\tdeepEqual( !!extractedData[ '5' ].content, true, 'Content extracted for tag with mw:Entity' );\n\t\tparser = new Parser( new MwContextualizer() );\n\t\tparser.init();\n\t\tparser.write( corruptedMTInput );\n\t\tconst expandedDoc = parser.builder.doc.expand( extractedData );\n\t\tdeepEqual(\n\t\t\tnormalize( expandedDoc.getHtml() ),\n\t\t\tnormalize( sanitizedExpandedDoc ),\n\t\t\t'Expanded the corrupted document by ignoring modified style and script content'\n\t\t);\n\t} );\n\n\tit( 'test HTML compaction roundtrip with template with empty content', () => {\n\t\tconst testXhtmlFile = dirname + '/data/text-inline-template-empty-content.html';\n\t\tconst contentForReduce = readFileSync( testXhtmlFile, 'utf8' ).replace( /^\\s+|\\s+$/, '' );\n\t\tconst parser = new Parser( new MwContextualizer() );\n\t\tparser.init();\n\t\tparser.write( contentForReduce );\n\t\tconst { reducedDoc, extractedData } = parser.builder.doc.reduce();\n\t\tconst reducedParser = new Parser( new MwContextualizer() );\n\t\treducedParser.init();\n\t\treducedParser.write( reducedDoc.getHtml() );\n\t\tdeepEqual( Object.keys( extractedData ).length, 6, 'Attributes for 6 tags extracted.' );\n\t\tconst expandedDoc = reducedParser.builder.doc.expand( extractedData );\n\t\tdeepEqual(\n\t\t\tnormalize( expandedDoc.getHtml() ),\n\t\t\tnormalize( contentForReduce ),\n\t\t\t'Restored the original html after reduce and expand.'\n\t\t);\n\t} );\n\n\tit( 'test getRootItem for ignoring blockspaces', () => {\n\t\tconst sourceDoc = `<section data-mw-section-id=\"25\" id=\"mwArE\">\n\t\t<p id=\"mwArI\">Sestak voted for the <a rel=\"mw:WikiLink\" href=\"./Improving_Head_Start_Act\"\n\t\t\t\ttitle=\"Improving Head Start Act\" id=\"mwArM\" class=\"new\">Improving Head Start Act</a> and the <a\n\t\t\t\trel=\"mw:WikiLink\" href=\"./College_Cost_Reduction_and_Access_Act\"\n\t\t\t\ttitle=\"College Cost Reduction and Access Act\" id=\"mwArQ\"\n\t\t\t\tclass=\"new\">College Cost Reduction and Access Act</a>.\n\t\t\t</p>\n\t\t</section>`;\n\n\t\tconst parser = new Parser( new MwContextualizer(), { isolateSegments: true } );\n\t\tparser.init();\n\t\tparser.write( sourceDoc );\n\t\tconst rootItem = parser.builder.doc.getRootItem();\n\t\tdeepEqual(\n\t\t\trootItem.name,\n\t\t\t'p',\n\t\t\t'getRootItem should ignore the blockspaces in the beginning of the document'\n\t\t);\n\t} );\n\n\tit( 'test getRootItem for not ignoring non-whitespace content in textblock', () => {\n\t\tconst sourceDoc = `<p id=\"mwFg\">The tensor product of <span about=\"#mwt10\" class=\"texhtml \"\n\t\tdata-mw=\"{}\" id=\"mwFw\" typeof=\"mw:Transclusion\"><i>V</i></span> and.\n\t\t</p>`;\n\n\t\tconst parser = new Parser( new MwContextualizer(), { isolateSegments: true } );\n\t\tparser.init();\n\t\tparser.write( sourceDoc );\n\t\tconst parsedDoc = parser.builder.doc;\n\t\tconst textblock = parsedDoc.items.find( ( item ) => item.type === 'textblock' );\n\t\tconst rootItem = textblock.item.getRootItem();\n\t\tdeepEqual(\n\t\t\trootItem,\n\t\t\tnull,\n\t\t\t'getRootItem of textblock should consider non-whitespace content inside its textchunks'\n\t\t);\n\t} );\n\n\tit( 'test getRootItem for ignoring whitespace content in textblock', () => {\n\t\tconst sourceDoc = `<p id=\"mwFg\">\n\t\t <span about=\"#mwt10\" class=\"texhtml \"\n\t\tdata-mw=\"{}\" id=\"mwFw\" typeof=\"mw:Transclusion\"><i>V</i></span> and.\n\t\t</p>`;\n\n\t\tconst parser = new Parser( new MwContextualizer(), { isolateSegments: true } );\n\t\tparser.init();\n\t\tparser.write( sourceDoc );\n\t\tconst parsedDoc = parser.builder.doc;\n\t\tconst textblock = parsedDoc.items.find( ( item ) => item.type === 'textblock' );\n\t\tconst rootItem = textblock.item.getRootItem();\n\t\tdeepEqual(\n\t\t\trootItem.name,\n\t\t\t'span',\n\t\t\t'getRootItem of textblock should ignore whitespace content inside its textchunks'\n\t\t);\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/lineardoc/translate.test.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/Apertium.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport assert from 'node:assert/strict';\nimport { forEach } from 'async';\nimport { deepEqual } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport Apertium from '../../lib/mt/Apertium.js';\n\n// In each case, below, just \"source\" and \"textTranslations\" should be sufficient for linearDoc\n// to derive \"target\". // The plaintext strings in \"textTranslations\" are real Apertium output.\n// They are pre-cached (Apertium is not actually called during the test), so that:\n// 1. Unit testing does not depend on Apertium\n// 2. Tests will not break if an Apertium upgrade changes some translations\nconst tests = [\n\t{\n\t\ttitle: 'All caps words',\n\t\tsource: '<p>A <b>Japanese</b> <i>BBC</i> article</p>',\n\t\ttarget: '<p>Un artículo de <i>BBC</i> <b>japonés</b></p>',\n\t\ttextTranslations: {\n\t\t\t'A Japanese BBC article': 'Un artículo de BBC japonés',\n\t\t\tBBC: 'BBC',\n\t\t\tJapanese: 'japonés'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Title caps one-to-many',\n\t\tsource: '<div>A <b>modern</b> Britain.</div>',\n\t\ttarget: '<div>Una Gran Bretaña <b>moderna</b>.</div>',\n\t\ttextTranslations: {\n\t\t\t'A modern Britain.': 'Una Gran Bretaña moderna.',\n\t\t\tmodern: 'Moderno'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Reordering with nested tags',\n\t\tsource: '<p>The <b>big <i>red</i></b> dog</p>',\n\t\ttarget: '<p>El perro <b><i>rojo</i></b> <b>grande</b></p>',\n\t\ttextTranslations: {\n\t\t\t'The big red dog': 'El perro rojo grande',\n\t\t\tbig: 'Grande',\n\t\t\tred: 'Rojo'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Many-to-one with nested tags',\n\t\tsource: '<p>He said \"<i>I tile <a href=\"x\">bathrooms</a>.</i>\"</p>',\n\t\ttarget: '<p>Diga que \"<i>enladrillo</i> <i><a href=\"x\">baños</a></i>.\"</p>',\n\t\ttextTranslations: {\n\t\t\t'He said \"I tile bathrooms.\"': 'Diga que \"enladrillo baños.\"',\n\t\t\t'I tile': 'Enladrillo',\n\t\t\tbathrooms: 'Baños\"'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Reordering at either ends of a tag',\n\t\tsource: '<p>The <b>big red</b> dog</p>',\n\t\ttarget: '<p>El perro <b>rojo grande</b></p>',\n\t\ttextTranslations: {\n\t\t\t'The big red dog': 'El perro rojo grande',\n\t\t\t'big red': 'Rojo grande'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Identical tags separated by whitespace',\n\t\tsource: '<p>The <b>big</b> <b>red</b> dog</p>',\n\t\ttarget: '<p>El perro <b>rojo</b> <b>grande</b></p>',\n\t\ttextTranslations: {\n\t\t\t'The big red dog': 'El perro rojo grande',\n\t\t\tbig: 'Grande',\n\t\t\tred: 'Rojo'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Non-identical links separated by whitespace',\n\t\tsource: '<p>The <a href=\"1\">big</a> <a href=\"2\">red</a> dog</p>',\n\t\ttarget: '<p>El perro <a href=\"2\">rojo</a> <a href=\"1\">grande</a></p>',\n\t\ttextTranslations: {\n\t\t\t'The big red dog': 'El perro rojo grande',\n\t\t\tbig: 'Grande',\n\t\t\tred: 'Rojo'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Find longest match among multiple matches',\n\t\tsource: '<p id=\"8\"><span class=\"cx-segment\" data-segmentid=\"9\"><a class=\"cx-link\" data-linkid=\"17\" href=\"./The_New_York_Times\" rel=\"mw:WikiLink\" title=\"The New York Times\">The New York Times</a>, which has an <b>executive editor</b> over the news pages and an <b>editorial page editor</b> over opinion pages.</span></p>',\n\t\ttarget: '<p id=\"8\"><span data-segmentid=\"9\" class=\"cx-segment\"><a title=\"The New York Times\" rel=\"mw:WikiLink\" href=\"./The_New_York_Times\" data-linkid=\"17\" class=\"cx-link\">The New York Times</a>, el cual tiene un <b>editor ejecutivo</b> sobre las páginas noticiosas y un <b>editor de página del editorial</b> encima páginas de opinión.</span></p>',\n\t\ttextTranslations: {\n\t\t\t'The New York Times, which has an executive editor over the news pages and an editorial page editor over opinion pages.': 'The New York Times, el cual tiene un editor ejecutivo sobre las páginas noticiosas y un editor de página del editorial encima páginas de opinión.',\n\t\t\t'The New York Times': 'The New York Times',\n\t\t\t'executive editor': 'editor ejecutivo',\n\t\t\t'editorial page editor': 'editor de página del editorial'\n\t\t}\n\t},\n\t{\n\t\ttitle: 'Do not translate content inside the style tags',\n\t\tsource: '<p id=\"8\"><style>b{color:red;}</style></p>',\n\t\ttarget: '<p id=\"8\"><style>b{color:red;}</style></p>',\n\t\ttextTranslations: {}\n\t}\n];\n\ndescribe( 'Apertium machine translation', () => {\n\tconst apertium = new Apertium( { conf: getConfig() } );\n\tassert.ok( apertium.conf.mt.Apertium.api !== undefined, 'Apertium API can be read from configuration' );\n\tforEach( tests, ( test ) => {\n\t\tit( 'Test: ' + test.title, () => {\n\t\t\tconst textTranslations = test.textTranslations;\n\t\t\t// Fake the actual Apertium call\n\t\t\tApertium.prototype.translateLines = function ( sourceLang, targetLang, sourceLines ) {\n\t\t\t\tconst targetLines = sourceLines.map( ( line ) => textTranslations[ line ] || 'X' + line + 'X' );\n\t\t\t\treturn Promise.resolve( targetLines );\n\t\t\t};\n\n\t\t\treturn apertium.translate( 'en', 'es', test.source ).then( ( target ) => {\n\t\t\t\tdeepEqual( target, test.target, test.title );\n\t\t\t} );\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/Elia.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport assert from 'node:assert/strict';\nimport { fails } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport Elia from '../../lib/mt/Elia.js';\n\ndescribe( 'Elia machine translation', () => {\n\tconst cxConfig = getConfig();\n\tcxConfig.mt.Elia.key = 'wrongkey';\n\tconst elia = new Elia( { conf: cxConfig } );\n\tassert.ok( elia.conf.mt.Elia.api !== undefined, 'Elia API can be read from configuration' );\n\tit( 'Should fail because of wrong key ', () => {\n\t\tconst testSourceContent = '<p>Esta es una <a href=\"/prueba\">prueba</a></p>';\n\t\tfails(\n\t\t\telia.translate( 'es', 'eu', testSourceContent ),\n\t\t\t( err ) => {\n\t\t\t\tif ( ( err instanceof Error ) && /value/.test( err ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/Google.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { fails } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport Google from '../../lib/mt/Google.js';\n\ndescribe( 'Google machine translation', () => {\n\tit( 'Should fail because of wrong key ', () => {\n\t\tconst cxConfig = getConfig();\n\t\tcxConfig.mt.Google.key = 'wrongkey';\n\t\tconst google = new Google( cxConfig );\n\t\tconst testSourceContent = '<p>This is a <a href=\"/Test\">test</a></p>';\n\t\tfails(\n\t\t\tgoogle.translate( 'en', 'ml', testSourceContent ),\n\t\t\t( err ) => {\n\t\t\t\tif ( ( err instanceof Error ) && /value/.test( err ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/LingCloud.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { fails } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport LingoCloud from '../../lib/mt/LingoCloud.js';\n\ndescribe( 'LingoCloud machine translation', () => {\n\tit( 'Should fail because of wrong key ', () => {\n\t\tconst cxConfig = getConfig();\n\t\tcxConfig.mt.LingoCloud.key = 'wrongkey';\n\t\tconst lingoCloud = new LingoCloud( cxConfig );\n\t\tconst testSourceContent = 'This is a random english text.';\n\t\tfails( lingoCloud.translate( 'en', 'zh', testSourceContent ), ( err ) => {\n\t\t\tif ( err instanceof Error && /value/.test( err ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/MTClient.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport assert from 'node:assert/strict';\nimport { deepEqual, fails } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport MTClient from '../../lib/mt/MTClient.js';\n\nconst testDataWithWrappedResult = {\n\tinput: `<section id=\"cxTargetSection0\">\n\t<p>\n\t<span data-segmentid=\"1\" class=\"cx-segment\">This is a sentence</span>\n\t</p>\n\t</section>`,\n\tmtIput: `<section id=\"cxTargetSection0\">\n\t<p>\n\t<div id=\"1\"><span id=\"2\">This is a sentence</span></div>\n\t</p>\n\t</section>`,\n\tmtResult: `<html><head></head><body><section id=\"cxTargetSection0\">\n\t<p>\n\t<div id=\"1\"><span id=\"2\">Esta es una oración</span></div>\n\t</p>\n\t</section></body></html>`,\n\tsourceLang: 'en',\n\ttargetLang: 'es'\n};\n\ndescribe( 'Machine translation with wrapped html result', () => {\n\tit( 'Should throw error', () => {\n\t\tconst cxConfig = getConfig();\n\t\t// Fake the actual call\n\t\tconst oldTranslateHTML = MTClient.prototype.translateHtml;\n\t\tMTClient.prototype.translateHtml = () => Promise.resolve( testDataWithWrappedResult.mtResult );\n\t\tconst mtClient = new MTClient( { conf: cxConfig } );\n\t\tfails(\n\t\t\tmtClient.translateReducedHtml(\n\t\t\t\ttestDataWithWrappedResult.sourceLang,\n\t\t\t\ttestDataWithWrappedResult.targetLang,\n\t\t\t\ttestDataWithWrappedResult.input\n\t\t\t),\n\t\t\t( err ) => {\n\t\t\t\tMTClient.prototype.translateHtml = oldTranslateHTML;\n\t\t\t\tassert.ok( err instanceof Error );\n\t\t\t\tassert.ok( /Unexpected content/.test( err.toString() ) );\n\t\t\t} );\n\t} );\n} );\n\nconst testDataForSpaceIssue = {\n\tinput: '<section id=\"cxTargetSection0\"><p><span data-segmentid=\"20\" class=\"cx-segment\"><b id=\"mwDA\">Oktay Rifat</b>, June 1914. </span><span data-segmentid=\"20\" class=\"cx-segment\"><b id=\"mwDA\">Oktay Rifat</b>, August 1914</span></p></section>',\n\tmtIput: '<section id=\"cxTargetSection0\"><p><div id=\"1\"><span id=\"2\"><b>Oktay Rifat</b>, June 1914. </span><span id=\"4\"><b>Oktay Rifat</b>, August 1914</span></div></p></section>',\n\tmtResult: '<section id=\"cxTargetSection0\"><p><div id=\"1\"><span id=\"2\"><b>Oktay Rifat</b> , junio de 1914.</span> <span id=\"4\"><b>Oktay Rifat</b> , augusto 1914</span></div></p></section>',\n\tsanitizedResult: '<section id=\"cxTargetSection0\"><p><span data-segmentid=\"20\" class=\"cx-segment\"><b>Oktay Rifat</b>, junio de 1914.</span> <span data-segmentid=\"20\" class=\"cx-segment\"><b>Oktay Rifat</b>, augusto 1914</span></p></section>',\n\tsourceLang: 'en',\n\ttargetLang: 'es'\n};\n\ndescribe( 'Machine translation result with extra spaces', () => {\n\tit( 'Should be cleaned up', () => {\n\t\tconst cxConfig = getConfig();\n\t\tconst oldTranslateHTML = MTClient.prototype.translateHtml;\n\t\tMTClient.prototype.translateHtml = () => Promise.resolve( testDataForSpaceIssue.mtResult );\n\t\tconst mtClient = new MTClient( cxConfig );\n\t\treturn mtClient.translateReducedHtml(\n\t\t\ttestDataForSpaceIssue.sourceLang,\n\t\t\ttestDataForSpaceIssue.targetLang,\n\t\t\ttestDataForSpaceIssue.input\n\t\t).then( ( result ) => {\n\t\t\tMTClient.prototype.translateHtml = oldTranslateHTML;\n\t\t\tdeepEqual( result, testDataForSpaceIssue.sanitizedResult );\n\t\t} );\n\t} );\n} );\n\nconst subSequenceTests = [\n\t{\n\t\ttext: 'They are subtropical and tropical flowers.',\n\t\tsubsequence: 'tropical',\n\t\tlanguage: 'en',\n\t\toccurrence: 0,\n\t\texpected: { start: 12, length: 8 }\n\t},\n\t{\n\t\ttext: 'This is test .[3]',\n\t\tsubsequence: '[3]',\n\t\tlanguage: 'en',\n\t\toccurrence: 0,\n\t\texpected: { start: 14, length: 3 }\n\t}\n];\ndescribe( 'Subsequence match finding', () => {\n\tit( 'Should return correct range mapping', () => {\n\t\tconst cxConfig = getConfig();\n\t\tconst mtClient = new MTClient( cxConfig );\n\t\tfor ( let i = 0; i < subSequenceTests.length; i++ ) {\n\t\t\tconst test = subSequenceTests[ i ];\n\t\t\tconst sequencePos = mtClient.findSubSequence(\n\t\t\t\ttest.text, test.subsequence, test.language, test.occurrence\n\t\t\t);\n\t\t\tdeepEqual( sequencePos, test.expected, 'Subsequence position correctly spotted.' );\n\t\t}\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/Template.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { deepEqual, notDeepEqual } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport TestClient from '../../lib/mt/TestClient.js';\n\nconst testSourceContent = `\n<section id=\"cxTargetSection12\" data-mw-cx-source=\"undefined\">\n <span about=\"#mwt51\" data-mw=\"{}\"\n id=\"mwZw\" typeof=\"mw:Transclusion\" data-ve-no-generated-contents=\"true\">\n </span>\n <link about=\"#mwt51\" href=\"./Category:A\" rel=\"mw:PageProp/Category\" data-ve-ignore=\"true\">\n <p about=\"#mwt51\">This is not translated</p>\n <p>This is translated</p>\n <div about=\"#mwt7\">This is not translated</div>\n</section>\n`;\n\ndescribe( 'Template translation', () => {\n\tit( 'should not translate the fragement contents.', async () => {\n\t\tconst cxConfig = getConfig();\n\t\tconst testClient = new TestClient( { conf: cxConfig } );\n\t\tconst result = await testClient.translate( 'en', 'es', testSourceContent );\n\t\tnotDeepEqual( result.includes( '[en→es]This is not translated' ), true );\n\t\tdeepEqual( result.includes( '[en→es]This is translated' ), true );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/Yandex.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { deepEqual, fails } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport Yandex from '../../lib/mt/Yandex.js';\n\nconst testData = {\n\tinput: `<section id=\"cxTargetSection0\">\n\t<p>\n\t<span data-segmentid=\"1\" class=\"cx-segment\">This is a sentence, <i id=\"mwCg\">\n\t<a href=\"./Auri_(album)\" rel=\"mw:WikiLink\" data-linkid=\"41\" class=\"mw-redirect cx-link\" id=\"mwCw\" title=\"Auri (album)\">a link in italics</a></i></span>\n\t</p>\n\t</section>`,\n\tmtIput: `<section id=\"cxTargetSection0\">\n\t<p>\n\t<div id=\"1\"><span id=\"2\">This is a sentence, <i id=\"mwCg\">\n\t<a id=\"3\">a link in italics</a></i></span></div>\n\t</p>\n\t</section>`,\n\tmtResult: `<section id=\"cxTargetSection0\">\n\t<p>\n\t<div id=\"1\"><span id=\"2\">Esta es una oración,, <i id=\"mwCg\">\n\t<a id=\"3\" href=\"badLocation\" onclick=\"bad();\">un enlace en cursiva</a></i></span></div>\n\t<script>Evil script</script>\n\t<iframe//src=jAva	script:alert(3)>\n\t</p>\n\t</section>`,\n\tsourceLang: 'en',\n\ttargetLang: 'es',\n\texpectedResult: `<section id=\"cxTargetSection0\">\n\t<p>\n\t<span data-segmentid=\"1\" class=\"cx-segment\">Esta es una oración,, <i id=\"mwCg\">\n\t<a title=\"Auri (album)\" rel=\"mw:WikiLink\" id=\"mwCw\" href=\"./Auri_(album)\" data-linkid=\"41\" class=\"mw-redirect cx-link\">un enlace en cursiva</a></i></span>\n\t</p>\n\t</section>`\n};\n\ndescribe( 'Yandex machine translation with corrupted result', () => {\n\tit( 'Should sanitize the MT output', () => {\n\t\tconst cxConfig = getConfig();\n\t\t// Fake the actual Yandex call\n\t\tconst oldTranslateHTML = Yandex.prototype.translateHtml;\n\t\tconst normalize = ( html ) => html.replace( /[\\t\\r\\n]+/g, '' );\n\t\tYandex.prototype.translateHtml = ( sourceLang, targetLang, mtInput ) => {\n\t\t\tdeepEqual( normalize( mtInput ), normalize( testData.mtIput ) );\n\t\t\treturn Promise.resolve( testData.mtResult );\n\t\t};\n\t\tconst yandex = new Yandex( cxConfig );\n\t\treturn yandex.translate( testData.sourceLang, testData.targetLang, testData.input )\n\t\t\t.then( ( result ) => {\n\t\t\t\tdeepEqual( normalize( result ), normalize( testData.expectedResult ) );\n\t\t\t\tYandex.prototype.translateHtml = oldTranslateHTML;\n\t\t\t} );\n\t} );\n} );\n\ndescribe( 'Yandex machine translation', () => {\n\tit( 'Should fail because of wrong key ', () => {\n\t\tconst cxConfig = getConfig();\n\t\tcxConfig.mt.Yandex.key = 'wrongkey';\n\t\tconst yandex = new Yandex( cxConfig );\n\t\tconst testSourceContent = '<p>This is a <a href=\"/Test\">test</a></p>';\n\t\tfails(\n\t\t\tyandex.translate( 'en', 'gu', testSourceContent ),\n\t\t\t( err ) => {\n\t\t\t\tif ( ( err instanceof Error ) && /value/.test( err ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mt/transform.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { deepEqual } from 'node:assert/strict';\nimport { each } from 'async';\nimport TransformLanguages from '../../config/transform.js';\n\ndescribe( 'Config transform tests', () => {\n\tconst cases = [\n\t\t{\n\t\t\tdescription: 'Simple cross product of languages',\n\t\t\tinput: {\n\t\t\t\tlanguages: [\n\t\t\t\t\t'af',\n\t\t\t\t\t'ca',\n\t\t\t\t\t'fr'\n\t\t\t\t]\n\t\t\t},\n\t\t\toutput: {\n\t\t\t\taf: [ 'ca', 'fr' ],\n\t\t\t\tca: [ 'af', 'fr' ],\n\t\t\t\tfr: [ 'af', 'ca' ]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tdescription: 'Do not translate between two variants of English',\n\t\t\tinput: {\n\t\t\t\tlanguages: [\n\t\t\t\t\t'af',\n\t\t\t\t\t'en',\n\t\t\t\t\t'simple'\n\t\t\t\t]\n\t\t\t},\n\t\t\toutput: {\n\t\t\t\taf: [ 'en', 'simple' ],\n\t\t\t\ten: [ 'af' ],\n\t\t\t\tsimple: [ 'af' ]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tdescription: 'Exclude \"notAsTarget\" languages',\n\t\t\tinput: {\n\t\t\t\tlanguages: [\n\t\t\t\t\t'af',\n\t\t\t\t\t'ca',\n\t\t\t\t\t'fr'\n\t\t\t\t],\n\t\t\t\tnotAsTarget: [ 'ca' ]\n\t\t\t},\n\t\t\toutput: {\n\t\t\t\taf: [ 'fr' ],\n\t\t\t\tca: [ 'af', 'fr' ],\n\t\t\t\tfr: [ 'af' ]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tdescription: 'Handle pairs in the configuration',\n\t\t\tinput: {\n\t\t\t\tlanguages: [\n\t\t\t\t\t'en',\n\t\t\t\t\t'ig',\n\t\t\t\t\t'tum',\n\t\t\t\t\t'sat'\n\t\t\t\t],\n\t\t\t\tpairs: {\n\t\t\t\t\ten: [ 'bcl' ]\n\t\t\t\t}\n\t\t\t},\n\t\t\toutput: {\n\t\t\t\ten: [\n\t\t\t\t\t'bcl',\n\t\t\t\t\t'ig',\n\t\t\t\t\t'tum',\n\t\t\t\t\t'sat'\n\t\t\t\t],\n\t\t\t\tig: [\n\t\t\t\t\t'en',\n\t\t\t\t\t'tum',\n\t\t\t\t\t'sat'\n\t\t\t\t],\n\t\t\t\tsat: [\n\t\t\t\t\t'en',\n\t\t\t\t\t'ig',\n\t\t\t\t\t'tum'\n\t\t\t\t],\n\t\t\t\ttum: [\n\t\t\t\t\t'en',\n\t\t\t\t\t'ig',\n\t\t\t\t\t'sat'\n\t\t\t\t]\n\n\t\t\t}\n\t\t}\n\t];\n\n\teach( cases, ( testcase, done ) => {\n\t\tit( testcase.description, () => {\n\t\t\tconst handler = new TransformLanguages( testcase.input );\n\t\t\tdeepEqual( handler.languages, testcase.output );\n\t\t\tdone();\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mw/MWPageLoaderTest.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":18,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":26},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":37,"column":27,"nodeType":"CallExpression","endLine":37,"endColumn":83},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":46,"column":5,"nodeType":"CallExpression","endLine":46,"endColumn":61}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { before, describe, it } from 'node:test';\nimport { readFileSync } from 'fs';\nimport { each } from 'async';\nimport { deepEqual } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport { Normalizer } from '../../lib/lineardoc/index.js';\nimport MWPageLoader from '../../lib/mw/MWPageLoader.js';\nimport { initApp } from '../../app.js';\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\nfunction normalize( html ) {\n\tconst normalizer = new Normalizer();\n\tnormalizer.init();\n\tnormalizer.write( html.replace( /[\\t\\r\\n]+/gm, '' ) );\n\treturn normalizer.getHtml();\n}\n\nconst tests = [\n\t{\n\t\tdesc: 'Add data-section-number attribute to every CX section',\n\t\tsource: 'test-data-section-number.html',\n\t\tsourceLanguage: 'en',\n\t\ttargetLanguage: 'es',\n\t\tresult: 'result-data-section-number.html'\n\t}\n];\ndescribe( 'MWPageLoader tests', () => {\n\tlet app;\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t} );\n\n\teach( tests, ( test ) => {\n\t\tit( 'Test: ' + test.desc, () => {\n\t\t\t// Fake the actual MWPageLoader fetch call\n\t\t\tMWPageLoader.prototype.fetch = () => {\n\t\t\t\tconst sourceContent = readFileSync( dirname + '/data/' + test.source, 'utf8' );\n\t\t\t\treturn Promise.resolve( { body: sourceContent } );\n\t\t\t};\n\t\t\tconst pageloader = new MWPageLoader( {\n\t\t\t\tcontext: app,\n\t\t\t\tsourceLanguage: test.sourceLanguage,\n\t\t\t\ttargetLanguage: test.targetLanguage\n\t\t\t} );\n\t\t\tconst expectedResultData = normalize(\n\t\t\t\treadFileSync( dirname + '/data/' + test.result, 'utf8' )\n\t\t\t);\n\t\t\treturn pageloader.getPage( 'mockPage', null, true ).then( ( processedPageContent ) => {\n\t\t\t\tdeepEqual( normalize( processedPageContent.content ), expectedResultData, test.desc );\n\t\t\t} );\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mw/SectionWrap.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":17,"column":33,"nodeType":"CallExpression","endLine":17,"endColumn":92}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { readFileSync } from 'fs';\nimport { forEach } from 'async';\nimport { load } from 'js-yaml';\nimport { deepEqual } from '../utils/assert.js';\nimport { MwContextualizer, Normalizer, Parser } from '../../lib/lineardoc/index.js';\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\nfunction normalize( html ) {\n\tconst normalizer = new Normalizer();\n\tnormalizer.init();\n\tnormalizer.write( html.replace( /[\\t\\r\\n]+/g, '' ) );\n\treturn normalizer.getHtml();\n}\n\nfunction getParsedDoc( content ) {\n\tconst pageloaderConfig = load( readFileSync( dirname + '/../../config/MWPageLoader.yaml' ) );\n\tconst parser = new Parser( new MwContextualizer(\n\t\t{ removableSections: pageloaderConfig.removableSections }\n\t), {\n\t\twrapSections: true\n\t} );\n\tparser.init();\n\tparser.write( content );\n\treturn parser.builder.doc;\n}\n\nconst sourceHTML = `<body>\n\t<section data-mw-section-id=\"0\">\n\t<p id=\"mwAb\">Paragraph <b>bold</b> <a href=\"/wiki/Title\">Title</a>.</p>\n\t</section>\n\t<section data-mw-section-id=\"1\">\n\t<h3>Heading</h3>\n\t<table><tr><td>data</td></tr></table>\n\t<div id=\"mwAc\">Content<div>innerdiv</div></div>\n\t</section>\n\t<section data-mw-section-id=\"2\">\n\t<p>Content<div>Div in paragraph</div></p>\n\t<ol><li>Item</li><li>Item</li></ol></section>\n\t<section data-mw-section-id=\"3\">\n\t<div typeof=\"mw:Transclusion\" about=\"#mwt1\" data-mw=\"{}\">Block template</div>\n\t</section>\n\t<section data-mw-section-id=\"4\">\n\t<span typeof=\"mw:Transclusion\" about=\"#mwt2\" data-mw=\"{}\">Some text content</span>\n\t<table about=\"#mwt2\"><tr><td>used value</td></tr></table>\n\t</section>\n\t<section data-mw-section-id=\"5\">\n\t<p>An inline <span typeof=\"mw:Transclusion\" about=\"#mwt3\" data-mw=\"{}\">template</span></p>\n\t</section>\n\t<section data-mw-section-id=\"6\">\n\t<span typeof=\"mw:Transclusion\" about=\"#mwt4\" data-mw=\"{}\">Template 4: Some text content</span>\n\t<table about=\"#mwt4\"><tr><td>Template 4: value</td></tr></table>\n\t<span typeof=\"mw:Transclusion\" about=\"#mwt5\" data-mw=\"{}\">Template 5: Some text content</span>\n\t<table about=\"#mwt5\"><tr><td>Template 5: value</td></tr></table>\n\t</section>\n\t<figure class=\"mw-default-size mw-halign-right\" id=\"mweA\" typeof=\"mw:File/Thumb\">\n\t<a href=\"./File:PriestleyFuseli.jpg\" id=\"mweQ\">\n\t<img alt=\"Alt text\" data-file-height=\"587\" data-file-type=\"bitmap\" data-file-width=\"457\" height=\"218\" id=\"mweg\" resource=\"./File:PriestleyFuseli.jpg\" src=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/PriestleyFuseli.jpg/170px-PriestleyFuseli.jpg\" srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/PriestleyFuseli.jpg/340px-PriestleyFuseli.jpg 2x, //upload.wikimedia.org/wikipedia/commons/thumb/4/4a/PriestleyFuseli.jpg/255px-PriestleyFuseli.jpg 1.5x\" width=\"170\" /></a>\n\t<figcaption id=\"mwew\">\n\t<a href=\"./Joseph_Priestley\" id=\"mwfA\" rel=\"mw:WikiLink\" title=\"Joseph Priestley\">Joseph Priestley</a> is usually given priority in the discovery.\n\t</figcaption>\n\t</figure>\n\t<dl id=\"mwAW8\">\n\t<dd id=\"mwAXA\">3 Fe + 4 H<sub id=\"mwAXE\">2</sub></dd>\n\t</dl>\n\t<link href=\"./Category:Category1\" id=\"mwCKQ\" rel=\"mw:PageProp/Category\" />\n\t<link rel=\"mw:PageProp/Category\" href=\"./Category:All_stub_articles\" about=\"#mwt8\" typeof=\"mw:Transclusion\" data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"nervous-system-drug-stub\",\"href\":\"./Template:Nervous-system-drug-stub\"},\"params\":{},\"i\":0}}]}'\n\tid=\"mwJg\" />\n\t<link rel=\"mw:PageProp/Category\" href=\"./Category:Nervous_system_drug_stubs\" about=\"#mwt8\" />\n\t<table class=\"plainlinks stub\" role=\"presentation\" style=\"background:transparent\" about=\"#mwt8\" id=\"mwJw\">\n\t<tbody></tbody>\n\t</table>\n\t<span id=\"empty_inline_annotation_transclusion\" about=\"#mwt335\" typeof=\"mw:Transclusion\" data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchor\",\"href\":\"./Template:Anchor\"},\"params\":{\"1\":{\"wt\":\"partial pressure\"}},\"i\":0}}]}'></span>\n\t<link rel=\"mw:PageProp/Category\" href=\"./Category:Wikipedia_indefinitely_move-protected_pages#Oxygen\" about=\"#mwt3\" typeof=\"mw:Transclusion\" data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"pp-move-indef\",\"href\":\"./Template:Pp-move-indef\"},\"params\":{},\"i\":0}}]}' id=\"mwBg\" />\n\t<section data-mw-section-id=\"61\">\n\t<div role=\"navigation\" class=\"navbox\" about=\"#mwt61\" typeof=\"mw:Transclusion\" data-mw=\"{}\">\n\tSection to be removed from output based on the navbox class\n\t</div>\n\t<link rel=\"mw:PageProp/Category\" href=\"./Category:Food_preparation\" about=\"#mwt61\">\n\t<span about=\"#mwt61\">Fragment 2</span>\n\t</section>\n\t</body>`;\n\nconst expectedSectionWrappedHTML = `<body>\n\t<section rel=\"cx:Section\"><p id=\"mwAb\">Paragraph <b>bold</b> <a href=\"/wiki/Title\">Title</a>.</p></section>\n\t<section rel=\"cx:Section\"><h3>Heading</h3></section>\n\t<section rel=\"cx:Section\"><table><tr><td>data</td></tr></table></section>\n\t<section rel=\"cx:Section\"><div id=\"mwAc\">Content<div>innerdiv</div></div></section>\n\t<section rel=\"cx:Section\"><p>Content<div>Div in paragraph</div></p></section>\n\t<section rel=\"cx:Section\"><ol><li>Item</li><li>Item</li></ol></section>\n\t<section rel=\"cx:Section\">\n\t<div typeof=\"mw:Transclusion\" about=\"#mwt1\" data-mw=\"{}\">Block template</div>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<span typeof=\"mw:Transclusion\" about=\"#mwt2\" data-mw='{}'>Some text content</span>\n\t<table about=\"#mwt2\"><tr><td>used value</td></tr></table>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<p>An inline <span about=\"#mwt3\" data-mw=\"{}\" typeof=\"mw:Transclusion\">template</span></p>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<span about=\"#mwt4\" data-mw=\"{}\" typeof=\"mw:Transclusion\">Template 4: Some text content</span>\n\t<table about=\"#mwt4\"><tr><td>Template 4: value</td></tr></table>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<span about=\"#mwt5\" data-mw=\"{}\" typeof=\"mw:Transclusion\">Template 5: Some text content</span>\n\t<table about=\"#mwt5\"><tr><td>Template 5: value</td></tr></table>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<figure class=\"mw-default-size mw-halign-right\" id=\"mweA\" typeof=\"mw:File/Thumb\" rel=\"cx:Figure\">\n\t<a href=\"./File:PriestleyFuseli.jpg\" id=\"mweQ\"><img alt=\"Alt text\" data-file-height=\"587\" data-file-type=\"bitmap\" data-file-width=\"457\" height=\"218\" id=\"mweg\" resource=\"./File:PriestleyFuseli.jpg\" src=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/PriestleyFuseli.jpg/170px-PriestleyFuseli.jpg\" srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/PriestleyFuseli.jpg/340px-PriestleyFuseli.jpg 2x, //upload.wikimedia.org/wikipedia/commons/thumb/4/4a/PriestleyFuseli.jpg/255px-PriestleyFuseli.jpg 1.5x\" width=\"170\" /></a>\n\t<figcaption id=\"mwew\">\n\t<a href=\"./Joseph_Priestley\" id=\"mwfA\" rel=\"mw:WikiLink\" title=\"Joseph Priestley\">Joseph Priestley</a> is usually given priority in the discovery.\n\t</figcaption>\n\t</figure>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<dl id=\"mwAW8\">\n\t<dd id=\"mwAXA\">3 Fe + 4 H<sub id=\"mwAXE\">2</sub></dd>\n\t</dl>\n\t</section>\n\t</body>`;\n\nconst sectionWithCategories = `\n\t<body class=\"mw-content-ltr sitedir-ltr ltr mw-body-content parsoid-body mediawiki mw-parser-output\" dir=\"ltr\" id=\"mwAA\" lang=\"en\">\n\t<section data-mw-section-id=\"0\">\n\t<p id=\"mwAdo\">\n\n\t<span about=\"#mwt87\" class=\"noviewer\" data-mw=\"{"parts":[{"template":{"target":{"wt":"Commonscat-inline","href":"./Template:Commonscat-inline"},"params":{"1":{"wt":"Attack aircraft"}},"i":0}}]}\" id=\"mwAds\" typeof=\"mw:Transclusion mw:Image\">\n\t<a href=\"./File:Commons-logo.svg\">\n\t<link href=\"./Category:Articles with inline\" about=\"#mwt87\" id=\"mwAd8\" rel=\"mw:PageProp/Category\" />\n\t<img alt=\"\" data-file-height=\"1376\" data-file-type=\"drawing\" data-file-width=\"1024\" height=\"16\" resource=\"./File:Commons-logo.svg\" src=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/12px-Commons-logo.svg.png\" srcset=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/24px-Commons-logo.svg.png 2x, //upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/18px-Commons-logo.svg.png 1.5x\" width=\"12\" />\n\t</a>\n\t</span>\n\t<span about=\"#mwt87\"> Media related to </span>\n\t<a about=\"#mwt87\" class=\"cx-link\" data-linkid=\"440\" href=\"https://commons.wikimedia.org/wiki/Category:Attack%20aircraft\" rel=\"mw:WikiLink/Interwiki\" title=\"commons:Category:Attack aircraft\">Attack aircraft</a>\n\t<span about=\"#mwt87\"> at Wikimedia Commons</span>\n\t</span>\n\t</p>\n\n\t<p>Another para</p>\n\t<link href=\"./Category:Fighter_aircraft\" id=\"mwAd4\" rel=\"mw:PageProp/Category\" />\n\t<link href=\"./Category:Attack_aircraft#%20\" id=\"mwAd8\" rel=\"mw:PageProp/Category\" />\n\n\t</section>\n\t</body>`;\n\nconst sectionWithCategoriesExpectedHtml = `\n\t<body class=\"mw-content-ltr sitedir-ltr ltr mw-body-content parsoid-body mediawiki mw-parser-output\" dir=\"ltr\" id=\"mwAA\" lang=\"en\">\n\t<section rel=\"cx:Section\">\n\n\t<p id=\"mwAdo\">\n\t<span about=\"#mwt87\" class=\"noviewer\" data-mw=\"{"parts":[{"template":{"target":{"wt":"Commonscat-inline","href":"./Template:Commonscat-inline"},"params":{"1":{"wt":"Attack aircraft"}},"i":0}}]}\" id=\"mwAds\" typeof=\"mw:Transclusion mw:Image\">\n\t<a href=\"./File:Commons-logo.svg\">\n\t<link about=\"#mwt87\" href=\"./Category:Articles with inline\" id=\"mwAd8\" rel=\"mw:PageProp/Category\" />\n\t<img alt=\"\" data-file-height=\"1376\" data-file-type=\"drawing\" data-file-width=\"1024\" height=\"16\" resource=\"./File:Commons-logo.svg\" src=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/12px-Commons-logo.svg.png\" srcset=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/24px-Commons-logo.svg.png 2x, //upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/18px-Commons-logo.svg.png 1.5x\" width=\"12\" />\n\t</a>\n\t</span><span about=\"#mwt87\"> Media related to </span>\n\t<a about=\"#mwt87\" class=\"cx-link\" data-linkid=\"440\" href=\"https://commons.wikimedia.org/wiki/Category:Attack%20aircraft\" rel=\"mw:WikiLink/Interwiki\" title=\"commons:Category:Attack aircraft\">Attack aircraft</a>\n\t<span about=\"#mwt87\"> at Wikimedia Commons</span></span>\n\t</p>\n\t</section>\n\n\t<section rel=\"cx:Section\">\n\t<p>Another para</p>\n\t</section>\n\t</body>`;\n\nconst nestedSectionsWithTransclusion = `\n\t<body>\n\t<section data-mw-section-id=\"2\" id=\"mwVw\">\n\t<p id=\"mw5Q\">\n\t<span about=\"#mwt216\" typeof=\"mw:Transclusion\" data-mw=\"{}\" id=\"mw7Q\">10,000</span>\n\t<span typeof=\"mw:Entity\" about=\"#mwt216\"> </span>\n\t<span about=\"#mwt216\">m (33,000</span>\n\t<span about=\"#mwt216\">mi)</span> in the\n\t</p>\n\t<section data-mw-section-id=\"3\" id=\"mwXw\">\n\t<h3>Heading</h3>\n\t<p id=\"mw6Q\">Para1</p>\n\t<p>Para2</p>\n\t</section>\n\t</section>\n\t</body>`;\n\nconst nestedSectionsWithTransclusionExpected = `\n\t<body>\n\t<section rel=\"cx:Section\">\n\t<p id=\"mw5Q\">\n\t<span about=\"#mwt216\" data-mw=\"{}\" id=\"mw7Q\" typeof=\"mw:Transclusion\">10,000</span>\n\t<span about=\"#mwt216\" typeof=\"mw:Entity\"> </span>\n\t<span about=\"#mwt216\">m (33,000</span>\n\t<span about=\"#mwt216\">mi)</span> in the</p>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<h3>Heading</h3>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<p id=\"mw6Q\">Para1</p>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t<p>Para2</p>\n\t</section>\n\t</body>`;\n\nconst sectionWithBlankTemplate = `\n<body>\n<section data-mw-section-id=\"0\" id=\"mwAQ\">\n<div class=\"shortdescription nomobile noexcerpt noprint searchaux\" style=\"display:none\" about=\"#mwt3\" typeof=\"mw:Transclusion\" data-mw=\"{}\" id=\"mwAw\">City in Virovitica-Podravina, Croatia</div>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Articles_with_short_description\" about=\"#mwt3\">\n<table class=\"infobox\" id=\"mwBV\"></table>\n</section>\n</body>`;\n\nconst sectionWithBlankTemplateExpected = `\n<body>\n<section rel=\"cx:Section\">\n<div about=\"#mwt3\" class=\"shortdescription nomobile noexcerpt noprint searchaux\" data-mw=\"{}\" id=\"mwAw\" style=\"display:none\" typeof=\"mw:Transclusion\">City in Virovitica-Podravina, Croatia</div>\n<link about=\"#mwt3\" href=\"./Category:Articles_with_short_description\" rel=\"mw:PageProp/Category\"></link>\n</section>\n<section rel=\"cx:Section\">\n<table class=\"infobox\" id=\"mwBV\"></table></section>\n</body>`;\n\nconst wholeBodySource = `\n<html>\n<head></head>\n<body id=\"mwAA\" lang=\"en\" >\n<section data-mw-section-id=\"1\" id=\"mwAQ\">\n<div typeof=\"mw:Transclusion\" about=\"#mwt2\" data-mw=\"{}\" id=\"mwAw\">Some text content</div>\n<table about=\"#mwt2\"><tr><td>used value</td></tr></table>\n</section>\n<section data-mw-section-id=\"2\" id=\"mwAQ\">\n<span typeof=\"mw:Transclusion\" about=\"#mwt3\" data-mw=\"{}\" id=\"mwAw\">Some text content</span>\n<table about=\"#mwt3\"><tr><td>used value</td></tr></table>\n</section>\n</body>\n</html>`;\n\nconst wholeBodyResult = `\n<html>\n<head></head>\n<body id=\"mwAA\" lang=\"en\">\n<section rel=\"cx:Section\">\n<div about=\"#mwt2\" data-mw=\"{}\" id=\"mwAw\" typeof=\"mw:Transclusion\">Some text content</div>\n<table about=\"#mwt2\"><tr><td>used value</td></tr></table>\n</section>\n<section rel=\"cx:Section\">\n<span about=\"#mwt3\" data-mw=\"{}\" id=\"mwAw\" typeof=\"mw:Transclusion\">Some text content</span>\n<table about=\"#mwt3\"><tr><td>used value</td></tr></table>\n</section>\n</body>\n</html>`;\n\nconst sectionWithMeta = `\n<body id=\"mwAA\" lang=\"he\">\n<section data-mw-section-id=\"0\" id=\"mwAQ\">\n<meta property=\"mw:PageProp/displaytitle\" content=\"פלמינג: האיש שרצה להיות בונד\" id=\"mwAg\" />\n<table class=\"infobox\" style=\"width: 270px; font-size: 95%;\" about=\"#mwt2\" typeof=\"mw:Transclusion\" data-mw='{}' id=\"mwAw\">\n\t<caption style=\"background: #C6C9FF; border:1px solid #aaaaaa; border-bottom:0px;\">פלמינג: האיש שרצה להיות\n\t\tבונד<br />Fleming: The Man Who Would Be Bond</caption>\n\t<tbody>\n\t\t<tr>\n\t\t\t<td colspan=\"2\" style=\"text-align:center\"></td>\n\t\t</tr>\n\t</tbody>\n</table>\n<link rel=\"mw:PageProp/Category\" href=\"./קטגוריה:ויקינתונים_-_השוואת_ערכים:_חסר\" about=\"#mwt2\" />\n<p id=\"mwBQ\"><b id=\"mwBg\">פלמינג: האיש שרצה להיות בונד</b></p>\n</section>\n</body>\n`;\n\nconst sectionWithMetaResult = `\n<body id=\"mwAA\" lang=\"he\">\n<section rel=\"cx:Section\">\n<meta content=\"פלמינג: האיש שרצה להיות בונד\" id=\"mwAg\" property=\"mw:PageProp/displaytitle\" />\n</section>\n<section rel=\"cx:Section\">\n<table about=\"#mwt2\" class=\"infobox\" data-mw=\"{}\" id=\"mwAw\" style=\"width: 270px; font-size: 95%;\" typeof=\"mw:Transclusion\">\n<caption style=\"background: #C6C9FF; border:1px solid #aaaaaa; border-bottom:0px;\">פלמינג: האיש שרצה להיותבונד\n<br />Fleming: The Man Who Would Be Bond</caption>\n<tbody>\n<tr><td colspan=\"2\" style=\"text-align:center\"></td></tr></tbody>\n</table><link about=\"#mwt2\" href=\"./קטגוריה:ויקינתונים_-_השוואת_ערכים:_חסר\" rel=\"mw:PageProp/Category\" />\n</section>\n<section rel=\"cx:Section\">\n<p id=\"mwBQ\"><b id=\"mwBg\">פלמינג: האיש שרצה להיות בונד</b>\n</p>\n</section>\n</body>\"\n`;\n\nconst sectionWithFigureInlineTemplate = `\n<html>\n\t<body>\n\t<h2 id=\"Enlaces_externos\">Enlaces externos</h2>\n\t<ul id=\"mwASA\">\n\t\t<li id=\"mwASE\"><a rel=\"mw:ExtLink\"\n\t\t\t\thref=\"http://www.portaloaca.com/historia/otroshistoria/94-la-leyenda-de-la-mano-negra.html\"\n\t\t\t\tclass=\"external text\" id=\"mwASI\">La leyenda de La Mano Negra</a></li>\n\t</ul>\n\t<span about=\"#mwt92\" typeof=\"mw:Transclusion\"\n\t\tdata-mw=\"{"parts":[{"template":{"target":{"wt":"commonscat","href":"./Plantilla:Commonscat"},"params":{"1":{"wt":"La Mano Negra"}},"i":0}},"\\\\n\\\\n[[Categoría:Historia de la provincia de Cádiz]]\\\\n[[Categoría:Derecho de Andalucía]]\\\\n[[Categoría:Casos judiciales de España]]\\\\n[[Categoría:Sociedades secretas]]\\\\n[[Categoría:Reinado de Alfonso XII]]\\\\n[[Categoría:Casos judiciales anarquistas]]\\\\n[[Categoría:Teorías conspirativas]]\\\\n[[Categoría:Historia del anarquismo]]\\\\n[[Categoría:Anarquismo en España]]\\\\n[[Categoría:España en 1882]]\\\\n[[Categoría:España en 1883]]\\\\n[[Categoría:España en 1884]]\\\\n[[Categoría:Política en 1882]]\\\\n[[Categoría:Política en 1883]]\\\\n[[Categoría:Política en 1884]]\\\\n[[Categoría:Atentados anarquistas]]"]}\"\n\t\tid=\"mwASk\">\n\t</span>\n\t<ul about=\"#mwt92\">\n\t\t<li>\n\t\t\t<span typeof=\"mw:Image\">\n\t\t\t<span>\n\t\t\t\t<img alt=\"\" resource=\"./Archivo:Commons-logo.svg\" src=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/15px-Commons-logo.svg.png\" data-file-width=\"1024\" data-file-height=\"1376\" data-file-type=\"drawing\" height=\"20\" width=\"15\" srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png 2x, //upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/23px-Commons-logo.svg.png 1.5x\">\n\t\t\t</span>\n\t\t\t</span>\n\t\t\t<a rel=\"mw:WikiLink\" href=\"./Wikimedia_Commons\" title=\"Wikimedia Commons\">Wikimedia Commons</a> alberga una categoría multimedia sobre<b><a rel=\"mw:WikiLink/Interwiki\" href=\"https://commons.wikimedia.org/wiki/Category:La%20Mano%20Negra\" title=\"commons:Category:La Mano Negra\">La Mano Negra</a></b>.\n\t\t\t<link rel=\"mw:PageProp/Category\" href=\"./Categoría:Historia_de_la_provincia_de_Cádiz\">\n\t\t\t<link rel=\"mw:PageProp/Category\" href=\"./Categoría:Derecho_de_Andalucía\">\n\t\t</li>\n\t</ul>\n</body>\n</html>\n`;\n\nconst sectionWithFigureInlineTemplateResult = `\n<html>\n<body>\n\t<section rel=\"cx:Section\">\n\t<h2 id=\"Enlaces_externos\">Enlaces externos</h2>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t\t<ul id=\"mwASA\">\n\t\t\t<li id=\"mwASE\">\n\t\t\t\t<a class=\"external text\" href=\"http://www.portaloaca.com/historia/otroshistoria/94-la-leyenda-de-la-mano-negra.html\" id=\"mwASI\" rel=\"mw:ExtLink\">La leyenda de La Mano Negra</a>\n\t\t\t</li>\n\t\t</ul>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t\t<span about=\"#mwt92\" data-mw=\"{"parts":[{"template":{"target":{"wt":"commonscat","href":"./Plantilla:Commonscat"},"params":{"1":{"wt":"La Mano Negra"}},"i":0}},"\\\\n\\\\n[[Categoría:Historia de la provincia de Cádiz]]\\\\n[[Categoría:Derecho de Andalucía]]\\\\n[[Categoría:Casos judiciales de España]]\\\\n[[Categoría:Sociedades secretas]]\\\\n[[Categoría:Reinado de Alfonso XII]]\\\\n[[Categoría:Casos judiciales anarquistas]]\\\\n[[Categoría:Teorías conspirativas]]\\\\n[[Categoría:Historia del anarquismo]]\\\\n[[Categoría:Anarquismo en España]]\\\\n[[Categoría:España en 1882]]\\\\n[[Categoría:España en 1883]]\\\\n[[Categoría:España en 1884]]\\\\n[[Categoría:Política en 1882]]\\\\n[[Categoría:Política en 1883]]\\\\n[[Categoría:Política en 1884]]\\\\n[[Categoría:Atentados anarquistas]]"]}\" id=\"mwASk\" typeof=\"mw:Transclusion\"></span>\n\t\t<ul about=\"#mwt92\">\n\t\t\t<li>\n\t\t\t\t<span typeof=\"mw:Image\">\n\t\t\t\t<span>\n\t\t\t\t\t<img alt=\"\" data-file-height=\"1376\" data-file-type=\"drawing\" data-file-width=\"1024\" height=\"20\" resource=\"./Archivo:Commons-logo.svg\" src=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/15px-Commons-logo.svg.png\" srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png 2x, //upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/23px-Commons-logo.svg.png 1.5x\" width=\"15\"></img>\n\t\t\t\t</span>\n\t\t\t\t</span>\n\t\t\t\t<a href=\"./Wikimedia_Commons\" rel=\"mw:WikiLink\" title=\"Wikimedia Commons\">Wikimedia Commons</a> alberga una categoría multimedia sobre<b><a href=\"https://commons.wikimedia.org/wiki/Category:La%20Mano%20Negra\" rel=\"mw:WikiLink/Interwiki\" title=\"commons:Category:La Mano Negra\">La Mano Negra</a></b>.\n\t\t\t</li>\n\t\t</ul>\n\t</section>\n</body>\n</html>\n`;\n\nconst sectionWithIgnorableTransclusionFragment = `\n<body>\n\t<section data-mw-section-id=\"0\" id=\"mwAQ\">\n\t\t<span about=\"#mwt4\" typeof=\"mw:Transclusion\"\n\t\t\tdata-mw=\"{"parts":[{"template":{"target":{"wt":"Generations Sidebar","href":"./Template:Generations_Sidebar"},"params":{},"i":0}}]}\"\n\t\t\tid=\"mwCA\">\n\t\t</span>\n\t\t<table class=\"vertical-navbox nowraplinks plainlist\"\n\t\t\tabout=\"#mwt4\" id=\"mwCQ\">\n\t\t\t<tbody>\n\t\t\t</tbody>\n\t\t</table>\n\t</section>\n\t<section data-mw-section-id=\"1\" id=\"mwFg\">\n\t\t<h2 id=\"Terminology\">Terminology</h2>\n\t</section>\n</body>\n`;\nconst sectionWithIgnorableTransclusionFragmentResult = `\n<body>\n\t<section rel=\"cx:Section\">\n\t\t<span about=\"#mwt4\" typeof=\"mw:Transclusion\"\n\t\t\tdata-mw=\"{"parts":[{"template":{"target":{"wt":"Generations Sidebar","href":"./Template:Generations_Sidebar"},"params":{},"i":0}}]}\"\n\t\t\tid=\"mwCA\">\n\t\t</span>\n\t</section>\n\t<section rel=\"cx:Section\">\n\t\t<h2 id=\"Terminology\">Terminology</h2>\n\t</section>\n</body>\n`;\n\nconst sectionWithTemplateAndTemplateStyles = `\n<body>\n\t<section data-mw-section-id=\"0\" id=\"mwAQ\">\n\t<ul>\n\t<li>\n\t\t<link rel=\"mw-deduplicated-inline-style\" href=\"mw-data:TemplateStyles:r886058088\" about=\"#mwt79\"\n\t\ttypeof=\"mw:Extension/templatestyles mw:Transclusion\"\n\t\tdata-mw=\"{"parts":[{"template":{"target":{"wt":"ISBN","href":"./Template:ISBN"},"params":{"1":{"wt":"0-7100-9224-5"}},"i":0}}]}\"\n\t\tid=\"mwAQE\">\n\n\t\t<a rel=\"mw:WikiLink\" href=\"./International_Standard_Book_Number\"\n\t\ttitle=\"International Standard Book Number\" about=\"#mwt79\">ISBN</a>\n\n\t\t<span typeof=\"mw:Entity\"\n\t\tabout=\"#mwt79\"> </span>\n\n\t\t<a rel=\"mw:WikiLink\" href=\"./Special:BookSources/0-7100-9224-5\"\n\t\ttitle=\"Special:BookSources/0-7100-9224-5\" about=\"#mwt79\" id=\"mwAQI\">0-7100-9224-5</a>\n\n\t</li>\n\t</ul>\n\t</section>\n</body>\n`;\n\nconst sectionWithTemplateAndTemplateStylesResult = `\n<body>\n\t<section rel=\"cx:Section\">\n\t<ul>\n\t<li>\n\t\t<link rel=\"mw-deduplicated-inline-style\" href=\"mw-data:TemplateStyles:r886058088\" about=\"#mwt79\"\n\t\ttypeof=\"mw:Extension/templatestyles mw:Transclusion\"\n\t\tdata-mw=\"{"parts":[{"template":{"target":{"wt":"ISBN","href":"./Template:ISBN"},"params":{"1":{"wt":"0-7100-9224-5"}},"i":0}}]}\"\n\t\tid=\"mwAQE\">\n\t\t</link>\n\t\t<a rel=\"mw:WikiLink\" href=\"./International_Standard_Book_Number\"\n\t\ttitle=\"International Standard Book Number\" about=\"#mwt79\">ISBN</a>\n\n\t\t<span typeof=\"mw:Entity\"\n\t\tabout=\"#mwt79\"> </span>\n\n\t\t<a rel=\"mw:WikiLink\" href=\"./Special:BookSources/0-7100-9224-5\"\n\t\ttitle=\"Special:BookSources/0-7100-9224-5\" about=\"#mwt79\" id=\"mwAQI\">0-7100-9224-5</a>\n\n\t</li>\n\t</ul>\n\t</section>\n</body>\n`;\n\nconst tests = [\n\t{\n\t\tdesc: 'section has common pattern of elements',\n\t\tsource: sourceHTML,\n\t\tresult: expectedSectionWrappedHTML,\n\t\tcategories: 1\n\t},\n\t{\n\t\tdesc: 'section has categories to be extracted',\n\t\tsource: sectionWithCategories,\n\t\tresult: sectionWithCategoriesExpectedHtml,\n\t\tcategories: 2\n\t},\n\t{\n\t\tdesc: 'content has nested sections and tricky transclusion context',\n\t\tsource: nestedSectionsWithTransclusion,\n\t\tresult: nestedSectionsWithTransclusionExpected,\n\t\tcategories: 0\n\t},\n\t{\n\t\tdesc: 'content has blank template and then an unrelated table',\n\t\tsource: sectionWithBlankTemplate,\n\t\tresult: sectionWithBlankTemplateExpected,\n\t\tcategories: 0\n\t},\n\t{\n\t\tdesc: 'content is complete page content with html, head tags and body having two templates with fragments',\n\t\tsource: wholeBodySource,\n\t\tresult: wholeBodyResult,\n\t\tcategories: 0\n\t},\n\t{\n\t\tdesc: 'Content has self closing meta tag',\n\t\tsource: sectionWithMeta,\n\t\tresult: sectionWithMetaResult,\n\t\tcategories: 0\n\t},\n\t{\n\t\tdesc: 'Content has template fragments and one fragment is a section candidate. Section has categories too',\n\t\tsource: sectionWithFigureInlineTemplate,\n\t\tresult: sectionWithFigureInlineTemplateResult,\n\t\tcategories: 2\n\t},\n\t{\n\t\tdesc: 'Content has transclusion and one of its fragment get removed since it is ignorable.',\n\t\tsource: sectionWithIgnorableTransclusionFragment,\n\t\tresult: sectionWithIgnorableTransclusionFragmentResult,\n\t\tcategories: 0\n\t},\n\t{\n\t\tdesc: 'Content has transclusion and same element is removable templatestyle. So do not remove',\n\t\tsource: sectionWithTemplateAndTemplateStyles,\n\t\tresult: sectionWithTemplateAndTemplateStylesResult,\n\t\tcategories: 0\n\t}\n];\n\ndescribe( 'Section wrap tests', () => {\n\tforEach( tests, ( test ) => {\n\t\tconst parsedDoc = getParsedDoc( test.source );\n\t\tconst wrappedSectionDoc = parsedDoc.wrapSections();\n\t\tconst result = normalize( wrappedSectionDoc.getHtml() );\n\t\tconst expectedResultData = normalize( test.result );\n\t\tit( 'should parse correctly when ' + test.desc, () => {\n\t\t\tdeepEqual( result, expectedResultData );\n\t\t} );\n\t\tit( 'should extract correct number of categories when ' + test.desc, () => {\n\t\t\tdeepEqual( parsedDoc.categories.length, test.categories );\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mw/TitlePairRequest.test.js","messages":[],"suppressedMessages":[{"ruleId":"no-loop-func","severity":2,"message":"Function declared in a loop contains unsafe references to variable(s) 'api'.","line":30,"column":68,"nodeType":"ArrowFunctionExpression","messageId":"unsafeRefs","endLine":37,"endColumn":4,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/mw/TitlePairTests.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/mw/TitlePairTests.mocks.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/segmentation/CXSegmenter.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":24,"column":19,"nodeType":"CallExpression","endLine":24,"endColumn":75},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":30,"column":3,"nodeType":"CallExpression","endLine":30,"endColumn":59}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { readFileSync } from 'fs';\nimport { deepEqual } from '../utils/assert.js';\nimport { MwContextualizer, Normalizer, Parser } from '../../lib/lineardoc/index.js';\nimport Segmenter from '../../lib/segmentation/CXSegmenter.js';\nimport allTests from './SegmentationTests.json' assert { type: 'json' };\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\nfunction normalize( html ) {\n\tconst normalizer = new Normalizer();\n\tnormalizer.init();\n\tnormalizer.write( html.replace( /[\\t\\r\\n]+/gm, '' ) );\n\treturn normalizer.getHtml();\n}\n\nfunction getParsedDoc( content ) {\n\tconst parser = new Parser( new MwContextualizer() );\n\tparser.init();\n\tparser.write( content );\n\treturn parser.builder.doc;\n}\n\nfunction runTest( test, lang ) {\n\tconst testData = readFileSync( dirname + '/data/' + test.source, 'utf8' );\n\tconst parsedDoc = getParsedDoc( testData );\n\tconst segmenter = new Segmenter();\n\tconst segmentedLinearDoc = segmenter.segment( parsedDoc, lang );\n\tconst result = normalize( segmentedLinearDoc.getHtml() );\n\tconst expectedResultData = normalize(\n\t\treadFileSync( dirname + '/data/' + test.result, 'utf8' )\n\t);\n\tit( 'should not have any errors when: ' + test.desc, () => {\n\t\tdeepEqual( result, expectedResultData, test.source + ': ' + test.desc || '' );\n\t} );\n}\n\nfor ( const lang in allTests ) {\n\tdescribe( 'Segmentation tests for ' + lang, () => {\n\t\tconst tests = allTests[ lang ];\n\t\tconst len = tests.length;\n\t\tfor ( let i = 0; i < len; i++ ) {\n\t\t\tif ( tests[ i ].skip ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trunTest( tests[ i ], lang );\n\t\t}\n\t} );\n}\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/segmentation/SegmentationTests.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/suggestions/SectionSuggestion.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":10,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\nimport { forEach } from 'async';\nimport { deepEqual } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport SectionSuggester from '../../lib/suggestion/SectionSuggester.js';\nimport MWApiRequestManager from '../../lib/mw/MWApiRequestManager.js';\n\nconst tests = [\n\t{\n\t\tsourceLanguage: 'en',\n\t\ttargetLanguage: 'ml',\n\t\tsourceTitle: 'Sitar',\n\t\ttargetTitle: 'സിത്താർ',\n\t\tsourceSections: [\n\t\t\t'Etymology',\n\t\t\t'History',\n\t\t\t'Playing',\n\t\t\t'See also',\n\t\t\t'External links',\n\t\t\t'References'\n\t\t],\n\t\ttargetSections: [\n\t\t\t'അവലംബം'\n\t\t],\n\t\texpectedResult: {\n\t\t\tsourceLanguage: 'en',\n\t\t\tsourceTitle: 'Sitar',\n\t\t\ttargetLanguage: 'ml',\n\t\t\ttargetTitle: 'സിത്താർ',\n\t\t\tsourceSections: [\n\t\t\t\t'Etymology',\n\t\t\t\t'History',\n\t\t\t\t'Playing',\n\t\t\t\t'See also',\n\t\t\t\t'External links',\n\t\t\t\t'References'\n\t\t\t],\n\t\t\ttargetSections: [\n\t\t\t\t'അവലംബം'\n\t\t\t],\n\t\t\tpresent: {\n\t\t\t\tReferences: 'അവലംബം'\n\t\t\t},\n\t\t\tmissing: {\n\t\t\t\tEtymology: 'പേരിന്റെ ഉത്ഭവം',\n\t\t\t\tHistory: 'ചരിത്രം',\n\t\t\t\tPlaying: 'വായിക്കുന്ന രീതി',\n\t\t\t\t'See also': 'ഇതും കാണുക',\n\t\t\t\t'External links': 'പുറം കണ്ണികൾ'\n\t\t\t}\n\t\t}\n\t}\n];\n\ndescribe( 'SectionSuggester tests', () => {\n\tforEach( tests, ( test ) => {\n\t\tit( 'should find present and missing sections', async () => {\n\t\t\tconst cxConfig = getConfig();\n\n\t\t\tconst api = new MWApiRequestManager( cxConfig );\n\t\t\tSectionSuggester.prototype.getSections = ( language ) => {\n\t\t\t\tif ( language === test.sourceLanguage ) {\n\t\t\t\t\treturn Promise.resolve( test.sourceSections );\n\t\t\t\t}\n\t\t\t\tif ( language === test.targetLanguage ) {\n\t\t\t\t\treturn Promise.resolve( test.targetSections );\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst sectionSuggestor = new SectionSuggester(\n\t\t\t\tapi,\n\t\t\t\tcxConfig.sectionmapping\n\t\t\t);\n\n\t\t\tawait sectionSuggestor.getMissingSections( test.sourceLanguage, test.sourceTitle, test.targetLanguage, test.targetTitle ).then( ( sections ) => {\n\t\t\t\tdeepEqual( sections, test.expectedResult );\n\t\t\t} );\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/testutils.js","messages":[{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found writeFileSync from package \"fs\" with non literal argument at index 0","line":22,"column":5,"nodeType":"CallExpression","endLine":22,"endColumn":65}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { existsSync, writeFileSync } from 'fs';\n\nclass TestUtils {\n\tconstructor( api ) {\n\t\tthis.api = api;\n\t}\n\n\tsetup( mocks ) {\n\t\tthis.api.clearCaches();\n\t\tthis.api.setRequestCache( new Map() );\n\t\tif ( existsSync( 'DUMPREQUESTS' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.api.loadCachedRequests( mocks );\n\t\tthis.api.enableOfflineMode();\n\t}\n\n\tdump( filename ) {\n\t\tif ( existsSync( 'DUMPREQUESTS' ) ) {\n\t\t\tthis.api.dumpCachedRequests().then( ( result ) => {\n\t\t\t\twriteFileSync( filename, JSON.stringify( result, null, 4 ) );\n\t\t\t\tthis.api.clearCaches();\n\t\t\t} );\n\t\t} else {\n\t\t\tthis.api.clearCaches();\n\t\t}\n\t}\n}\n\nexport default TestUtils;\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWLink.mocks.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWLink.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":25,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":33}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { after, before, describe, it } from 'node:test';\nimport { each } from 'async';\nimport Adapter from '../../lib/Adapter.js';\nimport MWApiRequestManager from '../../lib/mw/MWApiRequestManager.js';\nimport TestUtils from '../testutils.js';\nimport { deepEqual } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport { initApp } from '../../app.js';\n\nimport mocks from './MWLink.mocks.json' assert { type: 'json' };\nimport tests from './MWLink.test.json' assert { type: 'json' };\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\ndescribe( 'Link Adaptation tests', () => {\n\tlet app, api, mocker;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t\tapi = new MWApiRequestManager( app );\n\t\tmocker = new TestUtils( api );\n\t\tmocker.setup( mocks );\n\t} );\n\n\tafter( () => {\n\t\tmocker.dump( dirname + '/MWLink.mocks.json' );\n\t} );\n\n\teach( tests, ( test, done ) => {\n\t\tit( test.desc, () => {\n\t\t\tconst adapter = new Adapter( test.from, test.to, api, app );\n\t\t\tconst translationunit = adapter.getAdapter( test.source );\n\n\t\t\tdeepEqual( !!adapter.logger, true, 'Logger is set' );\n\t\t\treturn translationunit.adapt( test.source ).then( ( adaptedNode ) => {\n\t\t\t\tfor ( const attribute in [ 'href', 'rel', 'title' ] ) {\n\t\t\t\t\tdeepEqual(\n\t\t\t\t\t\tadaptedNode.attributes[ attribute ],\n\t\t\t\t\t\ttest.result.attributes[ attribute ],\n\t\t\t\t\t\t`Attribute ${ attribute } matches`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst expectedDataCX = JSON.parse( adaptedNode.attributes[ 'data-cx' ] );\n\t\t\t\tconst actualDataCX = test.result.attributes[ 'data-cx' ];\n\t\t\t\tdeepEqual(\n\t\t\t\t\texpectedDataCX.adapted,\n\t\t\t\t\tactualDataCX.adapted,\n\t\t\t\t\t'Property adapted of attribute data-cx matches'\n\t\t\t\t);\n\n\t\t\t\tfor ( const attribute in [ 'thumbnail', 'pageimage', 'description' ] ) {\n\t\t\t\t\tdeepEqual(\n\t\t\t\t\t\tactualDataCX.sourceTitle[ attribute ],\n\t\t\t\t\t\texpectedDataCX.sourceTitle[ attribute ],\n\t\t\t\t\t\t`Property sourceTitle.${ attribute } of attribute data-cx matches`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif ( expectedDataCX.adapted ) {\n\t\t\t\t\tfor ( const attribute in [\n\t\t\t\t\t\t'pageid',\n\t\t\t\t\t\t'thumbnail',\n\t\t\t\t\t\t'pageimage',\n\t\t\t\t\t\t'description'\n\t\t\t\t\t] ) {\n\t\t\t\t\t\tdeepEqual(\n\t\t\t\t\t\t\tactualDataCX.targetTitle[ attribute ],\n\t\t\t\t\t\t\texpectedDataCX.targetTitle[ attribute ],\n\t\t\t\t\t\t\t`Property targetTitle.${ attribute } of attribute data-cx matches`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdone( null );\n\t\t\t} );\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWLink.test.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWReference.mocks.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWReference.test.js","messages":[{"ruleId":"n/no-unsupported-features/node-builtins","severity":1,"message":"The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20'.","line":1,"column":25,"nodeType":"ImportSpecifier","messageId":"not-supported-till","endLine":1,"endColumn":33},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":38,"column":21,"nodeType":"CallExpression","endLine":38,"endColumn":77},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":53,"column":27,"nodeType":"CallExpression","endLine":53,"endColumn":83}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { after, before, describe, it } from 'node:test';\nimport assert from 'node:assert/strict';\nimport { readFileSync } from 'fs';\nimport { each } from 'async';\nimport { JSDOM } from 'jsdom';\nimport Adapter from '../../lib/Adapter.js';\nimport MWApiRequestManager from '../../lib/mw/MWApiRequestManager.js';\nimport TestClient from '../../lib/mt/TestClient.js';\nimport TestUtils from '../testutils.js';\nimport { deepEqual } from '../utils/assert.js';\nimport { getConfig } from '../../lib/util.js';\nimport { initApp } from '../../app.js';\n\nimport mocks from './MWReference.mocks.json' assert { type: 'json' };\nimport tests from './MWReference.test.json' assert { type: 'json' };\n\nconst dirname = new URL( '.', import.meta.url ).pathname;\ndescribe( 'Reference adaptation', () => {\n\tlet app, api, mocker;\n\n\tbefore( async () => {\n\t\tapp = await initApp( getConfig() );\n\t\tapi = new MWApiRequestManager( app );\n\t\tmocker = new TestUtils( api );\n\t\tmocker.setup( mocks );\n\t} );\n\n\tafter( () => {\n\t\tmocker.dump( dirname + '/MWReference.mocks.json' );\n\t} );\n\n\teach( tests, ( test, done ) => {\n\t\tit( test.desc, () => {\n\t\t\tapp.mtClient = new TestClient( app );\n\t\t\tapp.reduce = true;\n\t\t\tconst adapter = new Adapter( test.from, test.to, api, app );\n\t\t\tif ( typeof test.source === 'string' ) {\n\t\t\t\tconst content = readFileSync( dirname + '/data/' + test.source, 'utf8' );\n\t\t\t\tconst sourceDom = new JSDOM( content );\n\t\t\t\tconst sourceDomAttributes = sourceDom.window.document.querySelector( '[typeof=\"mw:Extension/ref\"]' ).attributes;\n\t\t\t\ttest.source = {\n\t\t\t\t\tname: 'span',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tid: sourceDomAttributes.getNamedItem( 'id' ).value,\n\t\t\t\t\t\t'data-mw': sourceDomAttributes.getNamedItem( 'data-mw' ).value,\n\t\t\t\t\t\trel: 'dc:references',\n\t\t\t\t\t\ttypeof: 'mw:Extension/ref',\n\t\t\t\t\t\tclass: 'mw-ref'\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tif ( typeof test.result === 'string' ) {\n\t\t\t\tconst resultContent = readFileSync( dirname + '/data/' + test.result, 'utf8' );\n\t\t\t\tconst resultDom = new JSDOM( resultContent );\n\t\t\t\tconst resultsDomAttributes = resultDom.window.document.querySelector( '[typeof=\"mw:Extension/ref\"]' ).attributes;\n\t\t\t\ttest.result = {\n\t\t\t\t\tname: 'span',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\t'data-cx': JSON.parse( resultsDomAttributes.getNamedItem( 'data-cx' ).value )\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tassert.ok( adapter, 'There is an adapter for references' );\n\t\t\tconst translationunit = adapter.getAdapter( test.source );\n\t\t\tassert.ok( translationunit, 'There is an translationunit for content' );\n\n\t\t\treturn translationunit.adapt( test.source ).then( ( adaptedNode ) => {\n\t\t\t\tconst actualDataCX = JSON.parse( adaptedNode.attributes[ 'data-cx' ] );\n\t\t\t\tconst expectedDataCX = test.result.attributes[ 'data-cx' ];\n\t\t\t\tdeepEqual( actualDataCX, expectedDataCX, 'data-cx matches' );\n\n\t\t\t\tif ( test.result.attributes[ 'data-mw' ] ) {\n\t\t\t\t\tconst expectedDataMW = test.result.attributes[ 'data-mw' ];\n\t\t\t\t\tconst actualDataMW = JSON.parse( adaptedNode.attributes[ 'data-mw' ] );\n\t\t\t\t\tdeepEqual( actualDataMW, expectedDataMW, 'data-mw matches' );\n\t\t\t\t}\n\n\t\t\t\tdone( null );\n\t\t\t} );\n\t\t} );\n\t} );\n} );\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWReference.test.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWTemplate.mocks.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWTemplate.test.js","messages":[],"suppressedMessages":[{"ruleId":"no-loop-func","severity":2,"message":"Function declared in a loop contains unsafe references to variable(s) 'app', 'app', 'api', 'app'.","line":30,"column":32,"nodeType":"ArrowFunctionExpression","messageId":"unsafeRefs","endLine":56,"endColumn":4,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/translationunits/MWTemplate.test.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]}]},{"filePath":"/src/repo/test/utils/assert.js","messages":[{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":7,"column":40,"nodeType":"NewExpression","endLine":7,"endColumn":62}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import assert from 'node:assert/strict';\n\nfunction deepEqual( result, expected, message ) {\n\n\ttry {\n\t\tif ( typeof expected === 'string' ) {\n\t\t\tassert.ok( result === expected || ( new RegExp( expected ).test( result ) ) );\n\t\t} else {\n\t\t\tassert.deepEqual( result, expected, message );\n\t\t}\n\t} catch ( e ) {\n\t\tconsole.log( 'Expected:\\n' + JSON.stringify( expected, null, 2 ) );\n\t\tconsole.log( 'Result:\\n' + JSON.stringify( result, null, 2 ) );\n\t\tthrow e;\n\t}\n\n}\n\n/**\n * Asserts whether the return status was as expected\n *\n * @param {Object} res\n * @param {string} expected\n */\nfunction status( res, expected ) {\n\n\tassert.deepEqual( res.status, expected,\n\t\t'Expected status to be ' + expected + ', but was ' + res.status );\n\n}\n\n/**\n * Asserts whether content type was as expected\n *\n * @param {Object} res\n * @param {string} expected\n */\nfunction contentType( res, expected ) {\n\n\tconst actual = res.headers[ 'content-type' ];\n\tassert.deepEqual( actual, expected,\n\t\t'Expected content-type to be ' + expected + ', but was ' + actual );\n\n}\n\nfunction notDeepEqual( result, expected, message ) {\n\n\ttry {\n\t\tassert.notDeepEqual( result, expected, message );\n\t} catch ( e ) {\n\t\tconsole.log( 'Not expected:\\n' + JSON.stringify( expected, null, 2 ) );\n\t\tconsole.log( 'Result:\\n' + JSON.stringify( result, null, 2 ) );\n\t\tthrow e;\n\t}\n\n}\n\nfunction fails( promise, onRejected ) {\n\n\tlet failed = false;\n\n\tfunction trackFailure( e ) {\n\t\tfailed = true;\n\t\treturn onRejected( e );\n\t}\n\n\tfunction check() {\n\t\tif ( !failed ) {\n\t\t\tthrow new Error( 'expected error was not thrown' );\n\t\t}\n\t}\n\n\treturn promise.catch( trackFailure ).then( check );\n\n}\n\nexport {\n\tdeepEqual,\n\tnotDeepEqual,\n\tfails,\n\tstatus,\n\tcontentType\n};\n","usedDeprecatedRules":[{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]}]
--- end ---
Disabling eslint rule 'es-x/no-hashbang' (broken in bin/.eslintrc.json) on bin/.eslintrc.json
Disabling eslint rule 'es-x/no-hashbang' (broken in bin/.eslintrc.json) on bin/.eslintrc.json
Disabling eslint rule 'es-x/no-hashbang' (broken in bin/.eslintrc.json) on bin/.eslintrc.json
Disabling eslint rule 'es-x/no-hashbang' (broken in bin/.eslintrc.json) on bin/.eslintrc.json
Disabling eslint rule 'es-x/no-hashbang' (broken in bin/.eslintrc.json) on bin/.eslintrc.json
Disabling eslint rule 'es-x/no-hashbang' (broken in bin/.eslintrc.json) on bin/.eslintrc.json
$ /usr/bin/npm ci
--- stderr ---
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: 'cxserver@1.2.1',
npm WARN EBADENGINE required: { node: '>=20' },
npm WARN EBADENGINE current: { node: 'v18.19.0', npm: '9.2.0' }
npm WARN EBADENGINE }
npm WARN deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm WARN deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm WARN deprecated npmlog@6.0.2: This package is no longer supported.
npm WARN deprecated @humanwhocodes/config-array@0.13.0: Use @eslint/config-array instead
npm WARN deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm WARN deprecated abab@2.0.6: Use your platform's native atob() and btoa() methods instead
npm WARN deprecated are-we-there-yet@3.0.1: This package is no longer supported.
npm WARN deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm WARN deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
npm WARN deprecated domexception@4.0.0: Use your platform's native DOMException instead
npm WARN deprecated gauge@4.0.4: This package is no longer supported.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options.
--- stdout ---
added 860 packages, and audited 861 packages in 11s
158 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
--- end ---
$ /usr/bin/npm test
--- stdout ---
> cxserver@1.2.1 test
> npm run lint && npm run unittest
> cxserver@1.2.1 lint
> eslint .
/src/repo/app.js
46:1 warning The type 'Express' is undefined jsdoc/no-undefined-types
81:34 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
84:25 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
222:9 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
223:10 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/bin/adapt.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/linear-reduce.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/linearize.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/mt.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/segment.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/bin/translate.js
1:1 error ES2023 Hashbang comments are forbidden es-x/no-hashbang
/src/repo/lib/Config.js
42:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
64:38 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
69:6 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
70:6 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
97:29 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/lib/adaptation/TemplateParameterMapper.js
110:5 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
110:7 warning Expected no linebreak before this expression implicit-arrow-linebreak
113:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
/src/repo/lib/lineardoc/MwContextualizer.js
143:35 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
/src/repo/lib/logging.js
7:1 warning The type 'winston' is undefined jsdoc/no-undefined-types
/src/repo/lib/mt/Apertium.js
37:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/Elia.js
92:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/Google.js
94:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/LingoCloud.js
74:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/MinT.js
55:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mt/Yandex.js
82:27 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/mw/MWPageLoader.js
19:33 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/lib/mw/MwApiRequest.js
60:26 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
106:26 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
193:10 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/lib/swagger-ui.js
26:9 warning Found readFile from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/lib/translationunits/MWCategory.js
15:41 warning Unsafe Regular Expression security/detect-unsafe-regex
/src/repo/lib/translationunits/MWFile.js
44:51 warning Unsafe Regular Expression security/detect-unsafe-regex
/src/repo/lib/translationunits/MWImage.js
123:68 warning Unsafe Regular Expression security/detect-unsafe-regex
/src/repo/lib/util.js
132:23 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/scripts/SectionTitleAlignment/alignwithmt.js
214:26 warning The 'fetch' is still an experimental feature and is not supported until Node.js 21.0.0. The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/scripts/template-mapping.js
108:7 warning Found existsSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
114:14 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/spec.yaml
195:1 warning This line has a length of 139. Maximum allowed is 100 max-len
246:1 warning This line has a length of 139. Maximum allowed is 100 max-len
468:1 warning This line has a length of 109. Maximum allowed is 100 max-len
493:1 warning This line has a length of 110. Maximum allowed is 100 max-len
499:1 warning This line has a length of 216. Maximum allowed is 100 max-len
540:1 warning This line has a length of 110. Maximum allowed is 100 max-len
547:1 warning This line has a length of 216. Maximum allowed is 100 max-len
589:1 warning This line has a length of 106. Maximum allowed is 100 max-len
606:1 warning This line has a length of 134. Maximum allowed is 100 max-len
/src/repo/test/adaptation/AdaptationTest.js
1:25 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/adaptation/SectionTest.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
31:20 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/adaptation/TemplateParameterMapper.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/app/app.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/app/spec.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
21:16 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
168:10 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
/src/repo/test/features/info/info.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/v1/page.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/features/v2/page.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/lineardoc/LinearDoc.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
24:22 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
25:24 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
26:26 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
70:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
86:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
134:27 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
204:28 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/mt/Apertium.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Elia.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Google.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/LingCloud.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/MTClient.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Template.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/Yandex.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mt/transform.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/mw/MWPageLoaderTest.js
1:18 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
37:27 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
46:5 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/mw/SectionWrap.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
17:33 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/segmentation/CXSegmenter.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
24:19 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
30:3 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/suggestions/SectionSuggestion.test.js
1:10 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/testutils.js
22:5 warning Found writeFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/translationunits/MWLink.test.js
1:25 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
/src/repo/test/translationunits/MWReference.test.js
1:25 warning The 'test.describe' is still an experimental feature and is not supported until Node.js 22.0.0 (backported: ^20.13.0). The configured version range is '>=20' n/no-unsupported-features/node-builtins
38:21 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
53:27 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename
/src/repo/test/utils/assert.js
7:40 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp
✖ 90 problems (6 errors, 84 warnings)
--- end ---
Traceback (most recent call last):
File "/venv/lib/python3.11/site-packages/runner-0.1.0-py3.11.egg/runner/__init__.py", line 1964, in main
libup.run(args.repo, args.output, args.branch)
File "/venv/lib/python3.11/site-packages/runner-0.1.0-py3.11.egg/runner/__init__.py", line 1902, in run
self.npm_upgrade(plan)
File "/venv/lib/python3.11/site-packages/runner-0.1.0-py3.11.egg/runner/__init__.py", line 1252, in npm_upgrade
self.npm_test()
File "/venv/lib/python3.11/site-packages/runner-0.1.0-py3.11.egg/runner/__init__.py", line 325, in npm_test
self.check_call(["npm", "test"])
File "/venv/lib/python3.11/site-packages/runner-0.1.0-py3.11.egg/runner/shell2.py", line 59, in check_call
res.check_returncode()
File "/usr/lib/python3.11/subprocess.py", line 502, in check_returncode
raise CalledProcessError(self.returncode, self.args, self.stdout,
subprocess.CalledProcessError: Command '['/usr/bin/npm', 'test']' returned non-zero exit status 1.