@shi-corp/development-utilities 1.1.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -9
- package/bin/config/{baseLintConfig.js → linter/base.js} +12 -39
- package/bin/config/{nextLintConfig.d.ts → linter/next.d.ts} +1 -1
- package/bin/config/linter/next.js +26 -0
- package/bin/config/next/base.js +3 -0
- package/bin/index.d.ts +3 -3
- package/bin/index.js +3 -3
- package/package.json +80 -64
- package/bin/config/baseNextConfig.js +0 -4
- package/bin/config/nextLintConfig.js +0 -13
- /package/bin/config/{baseLintConfig.d.ts → linter/base.d.ts} +0 -0
- /package/bin/config/{baseNextConfig.d.ts → next/base.d.ts} +0 -0
- /package/config/{baseTsConfig.json → typescript/base.json} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Development Utilities [](https://github.com/Software-Hardware-Integration-Lab/Development-Utilities/actions/workflows/Test-Unit.yml) [](https://github.com/Software-Hardware-Integration-Lab/Development-Utilities/actions/workflows/Test-Lint.yml) [](https://github.com/Software-Hardware-Integration-Lab/Development-Utilities/actions/workflows/github-code-scanning/codeql)
|
|
2
2
|
|
|
3
3
|
Shared development-time configurations for TypeScript, ESLint (flat config), and Next.js. These utilities are dev-only and should not ship with application runtime artifacts.
|
|
4
4
|
|
|
@@ -22,7 +22,7 @@ in tsconfig.json make these changes
|
|
|
22
22
|
|
|
23
23
|
```jsonc
|
|
24
24
|
{
|
|
25
|
-
"extends": "@shi-corp/development-utilities/config/baseTsConfig.json",
|
|
25
|
+
"extends": "@shi-corp/development-utilities/config/typescript/baseTsConfig.json",
|
|
26
26
|
"compilerOptions": {
|
|
27
27
|
"outDir": "./bin" // Adjust for your project
|
|
28
28
|
}
|
|
@@ -34,13 +34,26 @@ in tsconfig.json make these changes
|
|
|
34
34
|
|
|
35
35
|
This project is using flat file for eslint (best results achieved with version >=9.9.0) and the intention to be compatible with that style only:
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
In `eslint.config.(m)js` make these changes:
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
### Normal (Non-UI)
|
|
40
|
+
|
|
41
|
+
```TypeScript
|
|
42
|
+
import { baseLintConfig } from '@shi-corp/development-utilities';
|
|
43
|
+
|
|
44
|
+
export default [
|
|
45
|
+
...baseLintConfig,
|
|
46
|
+
// Add project-specific rules, ignores, or plugins here
|
|
47
|
+
];
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### User Interface (Next.JS)
|
|
51
|
+
|
|
52
|
+
```TypeScript
|
|
53
|
+
import { baseLintConfig } from '@shi-corp/development-utilities';
|
|
41
54
|
|
|
42
55
|
export default [
|
|
43
|
-
...
|
|
56
|
+
...nextLintConfig,
|
|
44
57
|
// Add project-specific rules, ignores, or plugins here
|
|
45
58
|
];
|
|
46
59
|
```
|
|
@@ -49,7 +62,7 @@ export default [
|
|
|
49
62
|
|
|
50
63
|
in next.config.(m)js make these changes
|
|
51
64
|
|
|
52
|
-
```
|
|
65
|
+
```TypeScript
|
|
53
66
|
import { nextConfig } from '@shi-corp/development-utilities';
|
|
54
67
|
|
|
55
68
|
export default {
|
|
@@ -67,9 +80,9 @@ export default {
|
|
|
67
80
|
## Compatibility
|
|
68
81
|
|
|
69
82
|
- Node.JS (Latest LTS)
|
|
70
|
-
- ES Lint >= 9.
|
|
83
|
+
- ES Lint >= 9.38.0
|
|
71
84
|
- TypeScript >= 5.9
|
|
72
|
-
- Next.JS >=
|
|
85
|
+
- Next.JS >= 16 (only if using the provided next config)
|
|
73
86
|
|
|
74
87
|
## License
|
|
75
88
|
|
|
@@ -1,25 +1,10 @@
|
|
|
1
|
-
import { defineConfig } from 'eslint/config';
|
|
1
|
+
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
2
2
|
import eslint from '@eslint/js';
|
|
3
3
|
import globals from 'globals';
|
|
4
4
|
import jsdoc from 'eslint-plugin-jsdoc';
|
|
5
5
|
import stylistic from '@stylistic/eslint-plugin';
|
|
6
6
|
import tseslint from 'typescript-eslint';
|
|
7
7
|
export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.configs['flat/recommended-typescript'], ...tseslint.configs.strictTypeChecked, ...tseslint.configs.stylisticTypeChecked, {
|
|
8
|
-
'ignores': [
|
|
9
|
-
'eslint.config.mjs',
|
|
10
|
-
'eslint.config.js',
|
|
11
|
-
'next.config.mjs',
|
|
12
|
-
'next.config.js',
|
|
13
|
-
'jest.config.mjs',
|
|
14
|
-
'node_modules/',
|
|
15
|
-
'bin/',
|
|
16
|
-
'dist/',
|
|
17
|
-
'out/',
|
|
18
|
-
'build/',
|
|
19
|
-
'.next/',
|
|
20
|
-
'next-env.d.ts'
|
|
21
|
-
]
|
|
22
|
-
}, {
|
|
23
8
|
'languageOptions': {
|
|
24
9
|
'globals': {
|
|
25
10
|
...globals.mocha,
|
|
@@ -39,9 +24,6 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
39
24
|
'@typescript-eslint/default-param-last': 'warn',
|
|
40
25
|
'@typescript-eslint/explicit-function-return-type': 'warn',
|
|
41
26
|
'@typescript-eslint/init-declarations': 'warn',
|
|
42
|
-
'@typescript-eslint/no-array-constructor': 'warn',
|
|
43
|
-
'@typescript-eslint/no-empty-function': 'warn',
|
|
44
|
-
'@typescript-eslint/no-implied-eval': 'warn',
|
|
45
27
|
'@typescript-eslint/no-invalid-this': 'warn',
|
|
46
28
|
'@typescript-eslint/no-loop-func': 'warn',
|
|
47
29
|
'@typescript-eslint/no-misused-promises': [
|
|
@@ -55,7 +37,6 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
55
37
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
56
38
|
'@typescript-eslint/no-restricted-imports': 'warn',
|
|
57
39
|
'@typescript-eslint/no-shadow': 'warn',
|
|
58
|
-
'@typescript-eslint/no-unused-expressions': 'warn',
|
|
59
40
|
'@typescript-eslint/no-unused-vars': [
|
|
60
41
|
'warn',
|
|
61
42
|
{
|
|
@@ -64,10 +45,7 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
64
45
|
}
|
|
65
46
|
],
|
|
66
47
|
'@typescript-eslint/no-use-before-define': 'warn',
|
|
67
|
-
'@typescript-eslint/no-useless-constructor': 'warn',
|
|
68
48
|
'@typescript-eslint/prefer-destructuring': 'warn',
|
|
69
|
-
'@typescript-eslint/prefer-promise-reject-errors': 'warn',
|
|
70
|
-
'@typescript-eslint/require-await': 'warn',
|
|
71
49
|
'@typescript-eslint/restrict-template-expressions': [
|
|
72
50
|
'warn',
|
|
73
51
|
{
|
|
@@ -100,7 +78,6 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
100
78
|
'id-length': 'warn',
|
|
101
79
|
'id-match': 'warn',
|
|
102
80
|
'init-declarations': 'off',
|
|
103
|
-
'jsdoc/check-alignment': 'warn',
|
|
104
81
|
'jsdoc/check-indentation': [
|
|
105
82
|
'warn',
|
|
106
83
|
{
|
|
@@ -147,8 +124,6 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
147
124
|
}
|
|
148
125
|
}
|
|
149
126
|
],
|
|
150
|
-
'jsdoc/require-param': 'warn',
|
|
151
|
-
'jsdoc/valid-types': 'warn',
|
|
152
127
|
'max-classes-per-file': 'warn',
|
|
153
128
|
'max-depth': [
|
|
154
129
|
'warn',
|
|
@@ -157,7 +132,6 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
157
132
|
'max-nested-callbacks': 'warn',
|
|
158
133
|
'new-cap': 'warn',
|
|
159
134
|
'no-alert': 'warn',
|
|
160
|
-
'no-array-constructor': 'off',
|
|
161
135
|
'no-bitwise': 'warn',
|
|
162
136
|
'no-caller': 'warn',
|
|
163
137
|
'no-console': 'warn',
|
|
@@ -166,7 +140,6 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
166
140
|
'no-div-regex': 'warn',
|
|
167
141
|
'no-duplicate-imports': 'warn',
|
|
168
142
|
'no-else-return': 'warn',
|
|
169
|
-
'no-empty-function': 'off',
|
|
170
143
|
'no-eq-null': 'warn',
|
|
171
144
|
'no-eval': 'warn',
|
|
172
145
|
'no-extend-native': 'warn',
|
|
@@ -174,7 +147,6 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
174
147
|
'no-extra-label': 'warn',
|
|
175
148
|
'no-implicit-coercion': 'warn',
|
|
176
149
|
'no-implicit-globals': 'warn',
|
|
177
|
-
'no-implied-eval': 'off',
|
|
178
150
|
'no-invalid-this': 'off',
|
|
179
151
|
'no-iterator': 'warn',
|
|
180
152
|
'no-label-var': 'warn',
|
|
@@ -215,23 +187,19 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
215
187
|
'no-sequences': 'warn',
|
|
216
188
|
'no-shadow': 'off',
|
|
217
189
|
'no-template-curly-in-string': 'warn',
|
|
218
|
-
'no-throw-literal': 'warn',
|
|
219
190
|
'no-undef-init': 'warn',
|
|
220
191
|
'no-undefined': 'warn',
|
|
221
192
|
'no-underscore-dangle': 'warn',
|
|
222
193
|
'no-unmodified-loop-condition': 'warn',
|
|
223
194
|
'no-unneeded-ternary': 'warn',
|
|
224
195
|
'no-unreachable-loop': 'warn',
|
|
225
|
-
'no-unused-expressions': 'off',
|
|
226
196
|
'no-unused-vars': 'off',
|
|
227
197
|
'no-use-before-define': 'off',
|
|
228
198
|
'no-useless-call': 'warn',
|
|
229
199
|
'no-useless-computed-key': 'warn',
|
|
230
200
|
'no-useless-concat': 'warn',
|
|
231
|
-
'no-useless-constructor': 'off',
|
|
232
201
|
'no-useless-rename': 'warn',
|
|
233
202
|
'no-useless-return': 'warn',
|
|
234
|
-
'no-var': 'warn',
|
|
235
203
|
'no-warning-comments': [
|
|
236
204
|
'warn',
|
|
237
205
|
{
|
|
@@ -248,20 +216,15 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
248
216
|
],
|
|
249
217
|
'operator-assignment': 'warn',
|
|
250
218
|
'prefer-arrow-callback': 'warn',
|
|
251
|
-
'prefer-const': 'warn',
|
|
252
219
|
'prefer-destructuring': 'off',
|
|
253
220
|
'prefer-exponentiation-operator': 'warn',
|
|
254
221
|
'prefer-named-capture-group': 'warn',
|
|
255
222
|
'prefer-numeric-literals': 'warn',
|
|
256
223
|
'prefer-object-spread': 'warn',
|
|
257
|
-
'prefer-promise-reject-errors': 'off',
|
|
258
224
|
'prefer-regex-literals': 'warn',
|
|
259
|
-
'prefer-rest-params': 'warn',
|
|
260
|
-
'prefer-spread': 'warn',
|
|
261
225
|
'prefer-template': 'warn',
|
|
262
226
|
'radix': 'warn',
|
|
263
227
|
'require-atomic-updates': 'warn',
|
|
264
|
-
'require-await': 'off',
|
|
265
228
|
'require-unicode-regexp': 'warn',
|
|
266
229
|
'sort-imports': 'warn',
|
|
267
230
|
'sort-keys': 'warn',
|
|
@@ -300,6 +263,10 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
300
263
|
'stylistic/function-paren-newline': 'warn',
|
|
301
264
|
'stylistic/generator-star-spacing': 'warn',
|
|
302
265
|
'stylistic/implicit-arrow-linebreak': 'warn',
|
|
266
|
+
'stylistic/indent': [
|
|
267
|
+
'warn',
|
|
268
|
+
4
|
|
269
|
+
],
|
|
303
270
|
'stylistic/jsx-quotes': 'warn',
|
|
304
271
|
'stylistic/key-spacing': 'warn',
|
|
305
272
|
'stylistic/keyword-spacing': 'warn',
|
|
@@ -471,4 +438,10 @@ export const eslintConfig = defineConfig(eslint.configs.recommended, jsdoc.confi
|
|
|
471
438
|
'contexts': ['TSInterfaceDeclaration']
|
|
472
439
|
}
|
|
473
440
|
}
|
|
474
|
-
}
|
|
441
|
+
}, globalIgnores([
|
|
442
|
+
'node_modules/',
|
|
443
|
+
'eslint.config.mjs',
|
|
444
|
+
'eslint.config.js',
|
|
445
|
+
'bin/',
|
|
446
|
+
'dist/'
|
|
447
|
+
]));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Baseline configuration used for linting Next.JS projects the SHI - Lab way. */
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const eslintConfig: import("eslint/config").Config[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
2
|
+
import { eslintConfig as baselineConfig } from './base.js';
|
|
3
|
+
import globals from 'globals';
|
|
4
|
+
import nextVitals from 'eslint-config-next/core-web-vitals';
|
|
5
|
+
import react from 'eslint-plugin-react';
|
|
6
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
7
|
+
export const eslintConfig = defineConfig([
|
|
8
|
+
...baselineConfig,
|
|
9
|
+
{
|
|
10
|
+
'languageOptions': { 'globals': { ...globals.browser } },
|
|
11
|
+
'settings': { 'react': { 'version': 'detect' } }
|
|
12
|
+
},
|
|
13
|
+
react.configs.flat['recommended'],
|
|
14
|
+
react.configs.flat['jsx-runtime'],
|
|
15
|
+
reactHooks.configs.flat.recommended,
|
|
16
|
+
...nextVitals,
|
|
17
|
+
globalIgnores([
|
|
18
|
+
'next.config.mjs',
|
|
19
|
+
'next.config.js',
|
|
20
|
+
'next-env.d.ts',
|
|
21
|
+
'.next/**',
|
|
22
|
+
'out/**',
|
|
23
|
+
'build/**',
|
|
24
|
+
'jest.config.mjs'
|
|
25
|
+
])
|
|
26
|
+
]);
|
package/bin/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { eslintConfig } from './config/
|
|
2
|
-
export { nextLintConfig } from './config/
|
|
3
|
-
export { nextConfig } from './config/
|
|
1
|
+
export { eslintConfig as baseLintConfig } from './config/linter/base.js';
|
|
2
|
+
export { eslintConfig as nextLintConfig } from './config/linter/next.js';
|
|
3
|
+
export { nextConfig } from './config/next/base.js';
|
package/bin/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { eslintConfig } from './config/
|
|
2
|
-
export { nextLintConfig } from './config/
|
|
3
|
-
export { nextConfig } from './config/
|
|
1
|
+
export { eslintConfig as baseLintConfig } from './config/linter/base.js';
|
|
2
|
+
export { eslintConfig as nextLintConfig } from './config/linter/next.js';
|
|
3
|
+
export { nextConfig } from './config/next/base.js';
|
package/package.json
CHANGED
|
@@ -1,66 +1,82 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
2
|
+
"name": "@shi-corp/development-utilities",
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Collection of configurations, settings and packages to be common across multiple products/repositories.",
|
|
5
|
+
"main": "bin/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build:Dev": "tsc",
|
|
9
|
+
"prebuild:Prod": "tsc -p prod.tsconfig.json --emitDeclarationOnly false",
|
|
10
|
+
"build:Prod": "tsc -p prod.tsconfig.json --removeComments false",
|
|
11
|
+
"lint": "eslint --max-warnings 0",
|
|
12
|
+
"test:Unit": "mocha"
|
|
13
|
+
},
|
|
14
|
+
"packageManager": "npm@11.6.2",
|
|
15
|
+
"devEngines": {
|
|
16
|
+
"runtime": {
|
|
17
|
+
"name": "node",
|
|
18
|
+
"version": ">=22.17.0",
|
|
19
|
+
"onFail": "error"
|
|
20
|
+
},
|
|
21
|
+
"packageManager": {
|
|
22
|
+
"name": "npm",
|
|
23
|
+
"onFail": "error"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=22.17.0"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/Software-Hardware-Integration-Lab/Development-Utilities"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"ESLint",
|
|
35
|
+
"config",
|
|
36
|
+
"lint",
|
|
37
|
+
"standardization",
|
|
38
|
+
"JSDoc",
|
|
39
|
+
"Stylistic",
|
|
40
|
+
"TypeScript",
|
|
41
|
+
"tsconfig",
|
|
42
|
+
"Next.js config"
|
|
43
|
+
],
|
|
44
|
+
"author": "Pasha Zayko <pasha_zayko@shi.com>",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/Software-Hardware-Integration-Lab/Development-Utilities/issues"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/Software-Hardware-Integration-Lab/Development-Utilities#readme",
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@eslint/js": "~9.38.0",
|
|
52
|
+
"@stylistic/eslint-plugin": "~5.5.0",
|
|
53
|
+
"eslint": "~9.38.0",
|
|
54
|
+
"eslint-config-next": "~16.0.0",
|
|
55
|
+
"eslint-plugin-jsdoc": "~61.1.9",
|
|
56
|
+
"eslint-plugin-react": "~7.37.5",
|
|
57
|
+
"eslint-plugin-react-hooks": "~7.0.1",
|
|
58
|
+
"typescript-eslint": "~8.46.2"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/chai": "~5.2.3",
|
|
62
|
+
"@types/eslint": "~9.6.1",
|
|
63
|
+
"@types/mocha": "~10.0.10",
|
|
64
|
+
"chai": "~6.2.0",
|
|
65
|
+
"mocha": "~11.7.4",
|
|
66
|
+
"next": "~16.0.0",
|
|
67
|
+
"typescript": "~5.9.3"
|
|
68
|
+
},
|
|
69
|
+
"overrides": {
|
|
70
|
+
"is-unicode-supported": "npm:@socketregistry/is-unicode-supported@^1",
|
|
71
|
+
"safe-buffer": "npm:@socketregistry/safe-buffer@^1"
|
|
72
|
+
},
|
|
73
|
+
"resolutions": {
|
|
74
|
+
"is-unicode-supported": "npm:@socketregistry/is-unicode-supported@^1",
|
|
75
|
+
"safe-buffer": "npm:@socketregistry/safe-buffer@^1"
|
|
76
|
+
},
|
|
77
|
+
"mocha": {
|
|
78
|
+
"recursive": true,
|
|
79
|
+
"spec": "bin/test/",
|
|
80
|
+
"color": true
|
|
81
|
+
}
|
|
66
82
|
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { eslintConfig as baselineConfig } from './baseLintConfig.js';
|
|
2
|
-
import { defineConfig } from 'eslint/config';
|
|
3
|
-
import globals from 'globals';
|
|
4
|
-
import react from 'eslint-plugin-react';
|
|
5
|
-
import reactHooks from 'eslint-plugin-react-hooks';
|
|
6
|
-
export const nextLintConfig = defineConfig(...baselineConfig, react.configs.flat['recommended'], react.configs.flat['jsx-runtime'], reactHooks.configs.flat['recommended'], {
|
|
7
|
-
'languageOptions': { 'globals': { ...globals.browser } },
|
|
8
|
-
'settings': {
|
|
9
|
-
'react': {
|
|
10
|
-
'version': 'detect'
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|