@dugararchit/cdk 0.0.0-dugararchit
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/_index.scss +8 -0
- package/a11y/_index.import.scss +2 -0
- package/a11y/_index.scss +102 -0
- package/a11y/a11y-prebuilt.scss +3 -0
- package/fesm2022/stagefright5-cdk-a11y.mjs +2381 -0
- package/fesm2022/stagefright5-cdk-a11y.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-accordion.mjs +267 -0
- package/fesm2022/stagefright5-cdk-accordion.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-bidi.mjs +185 -0
- package/fesm2022/stagefright5-cdk-bidi.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-clipboard.mjs +250 -0
- package/fesm2022/stagefright5-cdk-clipboard.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-coercion.mjs +128 -0
- package/fesm2022/stagefright5-cdk-coercion.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-collections.mjs +472 -0
- package/fesm2022/stagefright5-cdk-collections.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-drag-drop.mjs +3690 -0
- package/fesm2022/stagefright5-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-keycodes.mjs +159 -0
- package/fesm2022/stagefright5-cdk-keycodes.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-layout.mjs +246 -0
- package/fesm2022/stagefright5-cdk-layout.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-observers.mjs +203 -0
- package/fesm2022/stagefright5-cdk-observers.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-overlay.mjs +3033 -0
- package/fesm2022/stagefright5-cdk-overlay.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-platform.mjs +375 -0
- package/fesm2022/stagefright5-cdk-platform.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-portal.mjs +672 -0
- package/fesm2022/stagefright5-cdk-portal.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-scrolling.mjs +1399 -0
- package/fesm2022/stagefright5-cdk-scrolling.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-stepper.mjs +624 -0
- package/fesm2022/stagefright5-cdk-stepper.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-table.mjs +2346 -0
- package/fesm2022/stagefright5-cdk-table.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-testing-protractor.mjs +324 -0
- package/fesm2022/stagefright5-cdk-testing-protractor.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-testing-selenium-webdriver.mjs +364 -0
- package/fesm2022/stagefright5-cdk-testing-selenium-webdriver.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-testing-testbed.mjs +806 -0
- package/fesm2022/stagefright5-cdk-testing-testbed.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-testing.mjs +740 -0
- package/fesm2022/stagefright5-cdk-testing.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-text-field.mjs +453 -0
- package/fesm2022/stagefright5-cdk-text-field.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk-tree.mjs +945 -0
- package/fesm2022/stagefright5-cdk-tree.mjs.map +1 -0
- package/fesm2022/stagefright5-cdk.mjs +26 -0
- package/fesm2022/stagefright5-cdk.mjs.map +1 -0
- package/overlay/_index-deprecated.scss +13 -0
- package/overlay/_index.import.scss +13 -0
- package/overlay/_index.scss +148 -0
- package/overlay/overlay-prebuilt.scss +3 -0
- package/package.json +159 -0
- package/schematics/ng-update/test-cases/misc/global-stylesheets-test.scss +3 -0
- package/schematics/schematics/BUILD.bazel +104 -0
- package/schematics/schematics/README.md +4 -0
- package/schematics/schematics/collection.json +18 -0
- package/schematics/schematics/index.ts +22 -0
- package/schematics/schematics/migration.json +50 -0
- package/schematics/schematics/ng-add/index.spec.ts +50 -0
- package/schematics/schematics/ng-add/index.ts +39 -0
- package/schematics/schematics/ng-add/package-config.ts +62 -0
- package/schematics/schematics/ng-add/schema.json +16 -0
- package/schematics/schematics/ng-add/schema.ts +12 -0
- package/schematics/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__.template +53 -0
- package/schematics/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html.template +17 -0
- package/schematics/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.spec.ts.template +29 -0
- package/schematics/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts.template +43 -0
- package/schematics/schematics/ng-generate/drag-drop/index.spec.ts +205 -0
- package/schematics/schematics/ng-generate/drag-drop/index.ts +35 -0
- package/schematics/schematics/ng-generate/drag-drop/schema.json +93 -0
- package/schematics/schematics/ng-generate/drag-drop/schema.ts +11 -0
- package/schematics/schematics/ng-update/data/attribute-selectors.ts +29 -0
- package/schematics/schematics/ng-update/data/class-names.ts +50 -0
- package/schematics/schematics/ng-update/data/constructor-checks.ts +75 -0
- package/schematics/schematics/ng-update/data/css-selectors.ts +33 -0
- package/schematics/schematics/ng-update/data/element-selectors.ts +21 -0
- package/schematics/schematics/ng-update/data/index.ts +18 -0
- package/schematics/schematics/ng-update/data/input-names.ts +118 -0
- package/schematics/schematics/ng-update/data/method-call-checks.ts +63 -0
- package/schematics/schematics/ng-update/data/output-names.ts +42 -0
- package/schematics/schematics/ng-update/data/property-names.ts +151 -0
- package/schematics/schematics/ng-update/data/symbol-removal.ts +22 -0
- package/schematics/schematics/ng-update/devkit-file-system.ts +87 -0
- package/schematics/schematics/ng-update/devkit-migration-rule.ts +185 -0
- package/schematics/schematics/ng-update/devkit-migration.ts +47 -0
- package/schematics/schematics/ng-update/find-stylesheets.ts +43 -0
- package/schematics/schematics/ng-update/html-parsing/angular.ts +49 -0
- package/schematics/schematics/ng-update/html-parsing/elements.ts +66 -0
- package/schematics/schematics/ng-update/index.ts +113 -0
- package/schematics/schematics/ng-update/migrations/attribute-selectors.ts +83 -0
- package/schematics/schematics/ng-update/migrations/class-inheritance.ts +63 -0
- package/schematics/schematics/ng-update/migrations/class-names.ts +107 -0
- package/schematics/schematics/ng-update/migrations/constructor-signature.ts +170 -0
- package/schematics/schematics/ng-update/migrations/css-selectors.ts +83 -0
- package/schematics/schematics/ng-update/migrations/element-selectors.ts +75 -0
- package/schematics/schematics/ng-update/migrations/input-names.ts +83 -0
- package/schematics/schematics/ng-update/migrations/method-call-arguments.ts +70 -0
- package/schematics/schematics/ng-update/migrations/misc-template.ts +36 -0
- package/schematics/schematics/ng-update/migrations/output-names.ts +61 -0
- package/schematics/schematics/ng-update/migrations/property-names.ts +61 -0
- package/schematics/schematics/ng-update/migrations/symbol-removal.ts +51 -0
- package/schematics/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.ts +40 -0
- package/schematics/schematics/ng-update/public-api.ts +18 -0
- package/schematics/schematics/ng-update/test-cases/index.spec.ts +18 -0
- package/schematics/schematics/ng-update/test-cases/misc/external-resource-resolution.spec.ts +32 -0
- package/schematics/schematics/ng-update/test-cases/misc/external-resource-resolution_input.ts +22 -0
- package/schematics/schematics/ng-update/test-cases/misc/global-stylesheets-test.scss +3 -0
- package/schematics/schematics/ng-update/test-cases/misc/global-stylesheets.spec.ts +50 -0
- package/schematics/schematics/ng-update/test-cases/misc/global-stylesheets_input.ts +8 -0
- package/schematics/schematics/ng-update/test-cases/misc/method-call-checks.spec.ts +20 -0
- package/schematics/schematics/ng-update/test-cases/misc/method-call-checks_input.ts +18 -0
- package/schematics/schematics/ng-update/test-cases/misc/module-resolution.spec.ts +27 -0
- package/schematics/schematics/ng-update/test-cases/v13/misc/tilde-import-v13.spec.ts +149 -0
- package/schematics/schematics/ng-update/test-cases/v6/attribute-selectors_expected_output.ts +36 -0
- package/schematics/schematics/ng-update/test-cases/v6/attribute-selectors_input.ts +36 -0
- package/schematics/schematics/ng-update/test-cases/v6/class-names_expected_output.ts +8 -0
- package/schematics/schematics/ng-update/test-cases/v6/class-names_input.ts +8 -0
- package/schematics/schematics/ng-update/test-cases/v6/input-names_expected_output.ts +22 -0
- package/schematics/schematics/ng-update/test-cases/v6/input-names_input.ts +22 -0
- package/schematics/schematics/ng-update/test-cases/v6/property-names_expected_output.ts +64 -0
- package/schematics/schematics/ng-update/test-cases/v6/property-names_input.ts +64 -0
- package/schematics/schematics/ng-update/test-cases/v7/property-names_expected_output.ts +28 -0
- package/schematics/schematics/ng-update/test-cases/v7/property-names_input.ts +28 -0
- package/schematics/schematics/ng-update/typescript/base-types.ts +22 -0
- package/schematics/schematics/ng-update/typescript/imports.ts +54 -0
- package/schematics/schematics/ng-update/typescript/literal.ts +32 -0
- package/schematics/schematics/ng-update/typescript/module-specifiers.ts +39 -0
- package/schematics/schematics/ng-update/update-schematic.md +209 -0
- package/schematics/schematics/ng-update/upgrade-data.ts +79 -0
- package/schematics/schematics/paths.ts +15 -0
- package/schematics/schematics/testing/BUILD.bazel +27 -0
- package/schematics/schematics/testing/file-content.ts +20 -0
- package/schematics/schematics/testing/index.ts +14 -0
- package/schematics/schematics/testing/post-scheduled-tasks.ts +45 -0
- package/schematics/schematics/testing/resolve-bazel-path.ts +46 -0
- package/schematics/schematics/testing/test-app.ts +21 -0
- package/schematics/schematics/testing/test-case-setup.ts +236 -0
- package/schematics/schematics/testing/test-library.ts +21 -0
- package/schematics/schematics/testing/test-project.ts +40 -0
- package/schematics/schematics/testing/tsconfig.json +7 -0
- package/schematics/schematics/tsconfig.json +28 -0
- package/schematics/schematics/update-tool/BUILD.bazel +19 -0
- package/schematics/schematics/update-tool/component-resource-collector.ts +195 -0
- package/schematics/schematics/update-tool/file-system.ts +78 -0
- package/schematics/schematics/update-tool/index.ts +191 -0
- package/schematics/schematics/update-tool/logger.ts +23 -0
- package/schematics/schematics/update-tool/migration.ts +88 -0
- package/schematics/schematics/update-tool/public-api.ts +16 -0
- package/schematics/schematics/update-tool/target-version.ts +31 -0
- package/schematics/schematics/update-tool/tsconfig.json +7 -0
- package/schematics/schematics/update-tool/update-recorder.ts +14 -0
- package/schematics/schematics/update-tool/utils/decorators.ts +54 -0
- package/schematics/schematics/update-tool/utils/functions.ts +18 -0
- package/schematics/schematics/update-tool/utils/imports.ts +128 -0
- package/schematics/schematics/update-tool/utils/line-mappings.ts +84 -0
- package/schematics/schematics/update-tool/utils/parse-tsconfig.ts +25 -0
- package/schematics/schematics/update-tool/utils/property-name.ts +28 -0
- package/schematics/schematics/update-tool/utils/virtual-host.ts +116 -0
- package/schematics/schematics/update-tool/version-changes.ts +49 -0
- package/schematics/schematics/utils/ast/ng-module-imports.spec.ts +43 -0
- package/schematics/schematics/utils/ast/ng-module-imports.ts +102 -0
- package/schematics/schematics/utils/ast.ts +88 -0
- package/schematics/schematics/utils/build-component.ts +252 -0
- package/schematics/schematics/utils/get-project.ts +27 -0
- package/schematics/schematics/utils/html-manipulation.ts +105 -0
- package/schematics/schematics/utils/index.ts +19 -0
- package/schematics/schematics/utils/parse5-element.ts +34 -0
- package/schematics/schematics/utils/project-index-file.ts +21 -0
- package/schematics/schematics/utils/project-main-file.ts +26 -0
- package/schematics/schematics/utils/project-style-file.ts +53 -0
- package/schematics/schematics/utils/project-targets.ts +43 -0
- package/schematics/schematics/utils/project-tsconfig-paths.spec.ts +91 -0
- package/schematics/schematics/utils/project-tsconfig-paths.ts +49 -0
- package/schematics/schematics/utils/schematic-options.ts +65 -0
- package/schematics/schematics/utils/vendored-ast-utils/index.ts +599 -0
- package/scrolling/virtual-scroll-viewport.scss +87 -0
- package/table/table.scss +3 -0
- package/text-field/_index.import.scss +2 -0
- package/text-field/_index.scss +89 -0
- package/text-field/text-field-prebuilt.scss +4 -0
- package/types/stagefright5-cdk-a11y.d.ts +1160 -0
- package/types/stagefright5-cdk-accordion.d.ts +95 -0
- package/types/stagefright5-cdk-bidi.d.ts +95 -0
- package/types/stagefright5-cdk-clipboard.d.ts +116 -0
- package/types/stagefright5-cdk-coercion.d.ts +101 -0
- package/types/stagefright5-cdk-collections.d.ts +405 -0
- package/types/stagefright5-cdk-drag-drop.d.ts +1471 -0
- package/types/stagefright5-cdk-keycodes.d.ts +142 -0
- package/types/stagefright5-cdk-layout.d.ts +96 -0
- package/types/stagefright5-cdk-observers.d.ts +91 -0
- package/types/stagefright5-cdk-overlay.d.ts +1258 -0
- package/types/stagefright5-cdk-platform.d.ts +130 -0
- package/types/stagefright5-cdk-portal.d.ts +327 -0
- package/types/stagefright5-cdk-scrolling.d.ts +631 -0
- package/types/stagefright5-cdk-stepper.d.ts +302 -0
- package/types/stagefright5-cdk-table.d.ts +1128 -0
- package/types/stagefright5-cdk-testing-protractor.d.ts +146 -0
- package/types/stagefright5-cdk-testing-selenium-webdriver.d.ts +161 -0
- package/types/stagefright5-cdk-testing-testbed.d.ts +168 -0
- package/types/stagefright5-cdk-testing.d.ts +735 -0
- package/types/stagefright5-cdk-text-field.d.ts +171 -0
- package/types/stagefright5-cdk-tree.d.ts +522 -0
- package/types/stagefright5-cdk.d.ts +14 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {UnitTestTree} from '@angular-devkit/schematics/testing';
|
|
2
|
+
import {createTestCaseSetup} from '../../../../testing';
|
|
3
|
+
import {join} from 'path';
|
|
4
|
+
import {MIGRATION_PATH} from '../../../../paths';
|
|
5
|
+
|
|
6
|
+
describe('v13 tilde import migration', () => {
|
|
7
|
+
const PROJECT_PATH = '/projects/cdk-testing';
|
|
8
|
+
const TEST_PATH = join(PROJECT_PATH, 'src/test.scss');
|
|
9
|
+
let tree: UnitTestTree;
|
|
10
|
+
let _writeFile: (filePath: string, text: string) => void;
|
|
11
|
+
let runMigration: () => Promise<{logOutput: string}>;
|
|
12
|
+
|
|
13
|
+
beforeEach(async () => {
|
|
14
|
+
const testSetup = await createTestCaseSetup('migration-v13', MIGRATION_PATH, []);
|
|
15
|
+
tree = testSetup.appTree;
|
|
16
|
+
runMigration = testSetup.runFixers;
|
|
17
|
+
_writeFile = testSetup.writeFile;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/** Writes an array of lines as a single file. */
|
|
21
|
+
function writeLines(path: string, lines: string[]): void {
|
|
22
|
+
_writeFile(path, lines.join('\n'));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Reads a file and split it into an array where each item is a new line. */
|
|
26
|
+
function splitFile(path: string): string[] {
|
|
27
|
+
return tree.readContent(path).split('\n');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
it('should remove the tilde from angular imports', async () => {
|
|
31
|
+
writeLines(TEST_PATH, [
|
|
32
|
+
`@use '~@dugararchit/material' as mat;`,
|
|
33
|
+
`@import '~@dugararchit/material/theming';`,
|
|
34
|
+
`@import '~@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
35
|
+
|
|
36
|
+
`@include mat.button-theme();`,
|
|
37
|
+
`@include mat-core();`,
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
await runMigration();
|
|
41
|
+
|
|
42
|
+
expect(splitFile(TEST_PATH)).toEqual([
|
|
43
|
+
`@use '@dugararchit/material' as mat;`,
|
|
44
|
+
`@import '@dugararchit/material/theming';`,
|
|
45
|
+
`@import '@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
46
|
+
|
|
47
|
+
`@include mat.button-theme();`,
|
|
48
|
+
`@include mat-core();`,
|
|
49
|
+
]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should handle an arbitrary amount of whitespace', async () => {
|
|
53
|
+
writeLines(TEST_PATH, [
|
|
54
|
+
`@use '~@dugararchit/material' as mat;`,
|
|
55
|
+
|
|
56
|
+
`@include mat.core();`,
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
await runMigration();
|
|
60
|
+
|
|
61
|
+
expect(splitFile(TEST_PATH)).toEqual([
|
|
62
|
+
`@use '@dugararchit/material' as mat;`,
|
|
63
|
+
|
|
64
|
+
`@include mat.core();`,
|
|
65
|
+
]);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should preserve tilde after the start', async () => {
|
|
69
|
+
writeLines(TEST_PATH, [
|
|
70
|
+
`@use '~@angular/~material' as mat;`,
|
|
71
|
+
`@import '@dugararchit/cdk/~overlay-prebuilt.css';`,
|
|
72
|
+
|
|
73
|
+
`@include mat.core();`,
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
await runMigration();
|
|
77
|
+
|
|
78
|
+
expect(splitFile(TEST_PATH)).toEqual([
|
|
79
|
+
`@use '@angular/~material' as mat;`,
|
|
80
|
+
`@import '@dugararchit/cdk/~overlay-prebuilt.css';`,
|
|
81
|
+
|
|
82
|
+
`@include mat.core();`,
|
|
83
|
+
]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should handle different types of quotes', async () => {
|
|
87
|
+
writeLines(TEST_PATH, [
|
|
88
|
+
`@use "~@dugararchit/material" as mat;`,
|
|
89
|
+
`@import '~@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
90
|
+
|
|
91
|
+
`@include mat.button-theme();`,
|
|
92
|
+
`@include mat-core();`,
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
await runMigration();
|
|
96
|
+
|
|
97
|
+
expect(splitFile(TEST_PATH)).toEqual([
|
|
98
|
+
`@use "@dugararchit/material" as mat;`,
|
|
99
|
+
`@import '@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
100
|
+
|
|
101
|
+
`@include mat.button-theme();`,
|
|
102
|
+
`@include mat-core();`,
|
|
103
|
+
]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should preserve the tilde in non-angular imports', async () => {
|
|
107
|
+
writeLines(TEST_PATH, [
|
|
108
|
+
`@use '~@angular-momentum/material' as mat;`,
|
|
109
|
+
`@import '~@angular-momentum/material/theming';`,
|
|
110
|
+
`@import '@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
111
|
+
|
|
112
|
+
`@include mat.button-theme();`,
|
|
113
|
+
`@include mat-core();`,
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
await runMigration();
|
|
117
|
+
|
|
118
|
+
expect(splitFile(TEST_PATH)).toEqual([
|
|
119
|
+
`@use '~@angular-momentum/material' as mat;`,
|
|
120
|
+
`@import '~@angular-momentum/material/theming';`,
|
|
121
|
+
`@import '@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
122
|
+
|
|
123
|
+
`@include mat.button-theme();`,
|
|
124
|
+
`@include mat-core();`,
|
|
125
|
+
]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should remove remove .scss file extension', async () => {
|
|
129
|
+
writeLines(TEST_PATH, [
|
|
130
|
+
`@use '~@dugararchit/material.scss' as mat;`,
|
|
131
|
+
`@import '~@dugararchit/material/theming.scss';`,
|
|
132
|
+
`@import '~@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
133
|
+
|
|
134
|
+
`@include mat.button-theme();`,
|
|
135
|
+
`@include mat-core();`,
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
await runMigration();
|
|
139
|
+
|
|
140
|
+
expect(splitFile(TEST_PATH)).toEqual([
|
|
141
|
+
`@use '@dugararchit/material' as mat;`,
|
|
142
|
+
`@import '@dugararchit/material/theming';`,
|
|
143
|
+
`@import '@dugararchit/cdk/overlay-prebuilt.css';`,
|
|
144
|
+
|
|
145
|
+
`@include mat.button-theme();`,
|
|
146
|
+
`@include mat-core();`,
|
|
147
|
+
]);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {Component} from '@angular/core';
|
|
2
|
+
import * as core from '@angular/core';
|
|
3
|
+
import {By} from '@angular/platform-browser';
|
|
4
|
+
|
|
5
|
+
const a = By.css('[cdkPortalOutlet]');
|
|
6
|
+
const b = By.css('[cdkPortalOutlet]');
|
|
7
|
+
|
|
8
|
+
// These should not change because we only update string literals that are
|
|
9
|
+
// inside of a call expression.
|
|
10
|
+
const c = 'cdkPortalHost';
|
|
11
|
+
const d = 'portalHost';
|
|
12
|
+
|
|
13
|
+
@core.Component({
|
|
14
|
+
template: `
|
|
15
|
+
<div cdkPortalOutlet="E"></div>
|
|
16
|
+
<div [cdkPortalOutlet]="myPortal"></div>
|
|
17
|
+
`,
|
|
18
|
+
styles: [
|
|
19
|
+
'[cdkPortalOutlet] {background: red}',
|
|
20
|
+
'div[cdkPortalOutlet] {color: blue}'
|
|
21
|
+
]
|
|
22
|
+
})
|
|
23
|
+
class E {}
|
|
24
|
+
|
|
25
|
+
@Component({
|
|
26
|
+
standalone: false,
|
|
27
|
+
template: `
|
|
28
|
+
<div cdkPortalOutlet="F"></div>
|
|
29
|
+
<div [cdkPortalOutlet]="myPortal"></div>
|
|
30
|
+
`,
|
|
31
|
+
styles: [
|
|
32
|
+
'[cdkPortalOutlet] {background: red}',
|
|
33
|
+
'div[cdkPortalOutlet] {color: blue}'
|
|
34
|
+
]
|
|
35
|
+
})
|
|
36
|
+
class F {}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {Component} from '@angular/core';
|
|
2
|
+
import * as core from '@angular/core';
|
|
3
|
+
import {By} from '@angular/platform-browser';
|
|
4
|
+
|
|
5
|
+
const a = By.css('[cdkPortalHost]');
|
|
6
|
+
const b = By.css('[portalHost]');
|
|
7
|
+
|
|
8
|
+
// These should not change because we only update string literals that are
|
|
9
|
+
// inside of a call expression.
|
|
10
|
+
const c = 'cdkPortalHost';
|
|
11
|
+
const d = 'portalHost';
|
|
12
|
+
|
|
13
|
+
@core.Component({
|
|
14
|
+
template: `
|
|
15
|
+
<div cdkPortalHost="E"></div>
|
|
16
|
+
<div [cdkPortalHost]="myPortal"></div>
|
|
17
|
+
`,
|
|
18
|
+
styles: [
|
|
19
|
+
'[cdkPortalHost] {background: red}',
|
|
20
|
+
'div[cdkPortalHost] {color: blue}'
|
|
21
|
+
]
|
|
22
|
+
})
|
|
23
|
+
class E {}
|
|
24
|
+
|
|
25
|
+
@Component({
|
|
26
|
+
standalone: false,
|
|
27
|
+
template: `
|
|
28
|
+
<div portalHost="F"></div>
|
|
29
|
+
<div [portalHost]="myPortal"></div>
|
|
30
|
+
`,
|
|
31
|
+
styles: [
|
|
32
|
+
'[portalHost] {background: red}',
|
|
33
|
+
'div[portalHost] {color: blue}'
|
|
34
|
+
]
|
|
35
|
+
})
|
|
36
|
+
class F {}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import {CdkConnectedOverlay, CdkOverlayOrigin} from '@dugararchit/cdk/overlay';
|
|
2
|
+
import {CdkObserveContent} from '@dugararchit/cdk/observers';
|
|
3
|
+
import {CdkTrapFocus} from '@dugararchit/cdk/a11y';
|
|
4
|
+
|
|
5
|
+
const a = new CdkConnectedOverlay();
|
|
6
|
+
const b = new CdkOverlayOrigin();
|
|
7
|
+
const c = new CdkObserveContent();
|
|
8
|
+
const d = new CdkTrapFocus();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import {ConnectedOverlayDirective, OverlayOrigin} from '@dugararchit/cdk/overlay';
|
|
2
|
+
import {ObserveContent} from '@dugararchit/cdk/observers';
|
|
3
|
+
import {FocusTrapDirective} from '@dugararchit/cdk/a11y';
|
|
4
|
+
|
|
5
|
+
const a = new ConnectedOverlayDirective();
|
|
6
|
+
const b = new OverlayOrigin();
|
|
7
|
+
const c = new ObserveContent();
|
|
8
|
+
const d = new FocusTrapDirective();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {Component} from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
standalone: false,
|
|
5
|
+
template: `
|
|
6
|
+
<ng-template cdkConnectedOverlay
|
|
7
|
+
[cdkConnectedOverlayOrigin]="myOrigin"
|
|
8
|
+
[cdkConnectedOverlayPositions]="myPositions"
|
|
9
|
+
[cdkConnectedOverlayOffsetX]="myOffsetX"
|
|
10
|
+
[cdkConnectedOverlayOffsetY]="myOffsetY"
|
|
11
|
+
[cdkConnectedOverlayWidth]="myWidth"
|
|
12
|
+
[cdkConnectedOverlayHeight]="myHeight"
|
|
13
|
+
[cdkConnectedOverlayMinWidth]="myMinWidth"
|
|
14
|
+
[cdkConnectedOverlayMinHeight]="myMinHeight"
|
|
15
|
+
[cdkConnectedOverlayBackdropClass]="myBackdropClass"
|
|
16
|
+
[cdkConnectedOverlayScrollStrategy]="myScrollStrategy"
|
|
17
|
+
[cdkConnectedOverlayOpen]="isOpen"
|
|
18
|
+
[cdkConnectedOverlayHasBackdrop]="hasBackdrop">
|
|
19
|
+
</ng-template>
|
|
20
|
+
`
|
|
21
|
+
})
|
|
22
|
+
class A {}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {Component} from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
standalone: false,
|
|
5
|
+
template: `
|
|
6
|
+
<ng-template cdkConnectedOverlay
|
|
7
|
+
[origin]="myOrigin"
|
|
8
|
+
[positions]="myPositions"
|
|
9
|
+
[offsetX]="myOffsetX"
|
|
10
|
+
[offsetY]="myOffsetY"
|
|
11
|
+
[width]="myWidth"
|
|
12
|
+
[height]="myHeight"
|
|
13
|
+
[minWidth]="myMinWidth"
|
|
14
|
+
[minHeight]="myMinHeight"
|
|
15
|
+
[backdropClass]="myBackdropClass"
|
|
16
|
+
[scrollStrategy]="myScrollStrategy"
|
|
17
|
+
[open]="isOpen"
|
|
18
|
+
[hasBackdrop]="hasBackdrop">
|
|
19
|
+
</ng-template>
|
|
20
|
+
`
|
|
21
|
+
})
|
|
22
|
+
class A {}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
class CdkConnectedOverlay {
|
|
2
|
+
_deprecatedOrigin: any;
|
|
3
|
+
_deprecatedPositions: any;
|
|
4
|
+
_deprecatedOffsetX: any;
|
|
5
|
+
_deprecatedOffsetY: any;
|
|
6
|
+
_deprecatedWidth: any;
|
|
7
|
+
_deprecatedHeight: any;
|
|
8
|
+
_deprecatedMinWidth: any;
|
|
9
|
+
_deprecatedMinHeight: any;
|
|
10
|
+
_deprecatedBackdropClass: any;
|
|
11
|
+
_deprecatedScrollStrategy: any;
|
|
12
|
+
_deprecatedOpen: any;
|
|
13
|
+
_deprecatedHasBackdrop: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class CdkPortalOutlet {
|
|
17
|
+
_deprecatedPortal: any;
|
|
18
|
+
_deprecatedPortalHost: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class A {
|
|
22
|
+
self = {me: this};
|
|
23
|
+
|
|
24
|
+
constructor(private a: CdkConnectedOverlay) {}
|
|
25
|
+
|
|
26
|
+
onAngularClick() {
|
|
27
|
+
this.a.origin = '1';
|
|
28
|
+
this.a.positions = '2';
|
|
29
|
+
this.a.offsetX = '3';
|
|
30
|
+
this.a.offsetY = '4';
|
|
31
|
+
this.a.height = '5';
|
|
32
|
+
|
|
33
|
+
console.log(this.a.width || 10);
|
|
34
|
+
console.log(this.a.minWidth || this.a.minHeight);
|
|
35
|
+
|
|
36
|
+
this.self.me.a.backdropClass = ['a', 'b', 'c'];
|
|
37
|
+
|
|
38
|
+
const x = ({test: true} || this.a);
|
|
39
|
+
|
|
40
|
+
if (this.isConnectedOverlay(x)) {
|
|
41
|
+
x.scrollStrategy = 'myScrollStrategy';
|
|
42
|
+
x.open = false;
|
|
43
|
+
x.hasBackdrop = true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
isConnectedOverlay(val: any): val is CdkConnectedOverlay {
|
|
48
|
+
return val instanceof CdkConnectedOverlay;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class B {
|
|
53
|
+
self = {me: this};
|
|
54
|
+
|
|
55
|
+
constructor(protected a: CdkPortalOutlet) {}
|
|
56
|
+
|
|
57
|
+
onClick() {
|
|
58
|
+
this.a.portal = this.a.portal = 'myNewPortal';
|
|
59
|
+
|
|
60
|
+
if (this.self.me.a) {
|
|
61
|
+
console.log(this.a.portal || this.self.me.a.portal);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
class CdkConnectedOverlay {
|
|
2
|
+
_deprecatedOrigin: any;
|
|
3
|
+
_deprecatedPositions: any;
|
|
4
|
+
_deprecatedOffsetX: any;
|
|
5
|
+
_deprecatedOffsetY: any;
|
|
6
|
+
_deprecatedWidth: any;
|
|
7
|
+
_deprecatedHeight: any;
|
|
8
|
+
_deprecatedMinWidth: any;
|
|
9
|
+
_deprecatedMinHeight: any;
|
|
10
|
+
_deprecatedBackdropClass: any;
|
|
11
|
+
_deprecatedScrollStrategy: any;
|
|
12
|
+
_deprecatedOpen: any;
|
|
13
|
+
_deprecatedHasBackdrop: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class CdkPortalOutlet {
|
|
17
|
+
_deprecatedPortal: any;
|
|
18
|
+
_deprecatedPortalHost: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class A {
|
|
22
|
+
self = {me: this};
|
|
23
|
+
|
|
24
|
+
constructor(private a: CdkConnectedOverlay) {}
|
|
25
|
+
|
|
26
|
+
onAngularClick() {
|
|
27
|
+
this.a._deprecatedOrigin = '1';
|
|
28
|
+
this.a._deprecatedPositions = '2';
|
|
29
|
+
this.a._deprecatedOffsetX = '3';
|
|
30
|
+
this.a._deprecatedOffsetY = '4';
|
|
31
|
+
this.a._deprecatedHeight = '5';
|
|
32
|
+
|
|
33
|
+
console.log(this.a._deprecatedWidth || 10);
|
|
34
|
+
console.log(this.a._deprecatedMinWidth || this.a._deprecatedMinHeight);
|
|
35
|
+
|
|
36
|
+
this.self.me.a._deprecatedBackdropClass = ['a', 'b', 'c'];
|
|
37
|
+
|
|
38
|
+
const x = ({test: true} || this.a);
|
|
39
|
+
|
|
40
|
+
if (this.isConnectedOverlay(x)) {
|
|
41
|
+
x._deprecatedScrollStrategy = 'myScrollStrategy';
|
|
42
|
+
x._deprecatedOpen = false;
|
|
43
|
+
x._deprecatedHasBackdrop = true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
isConnectedOverlay(val: any): val is CdkConnectedOverlay {
|
|
48
|
+
return val instanceof CdkConnectedOverlay;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class B {
|
|
53
|
+
self = {me: this};
|
|
54
|
+
|
|
55
|
+
constructor(protected a: CdkPortalOutlet) {}
|
|
56
|
+
|
|
57
|
+
onClick() {
|
|
58
|
+
this.a._deprecatedPortal = this.a._deprecatedPortalHost = 'myNewPortal';
|
|
59
|
+
|
|
60
|
+
if (this.self.me.a) {
|
|
61
|
+
console.log(this.a._deprecatedPortalHost || this.self.me.a._deprecatedPortal);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {EventEmitter, OnInit} from '@angular/core';
|
|
2
|
+
|
|
3
|
+
class SelectionModel {
|
|
4
|
+
onChange = new EventEmitter<void>();
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class CdkConnectedOverlay {
|
|
8
|
+
flexibleDiemsions: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* Actual test case using the previously defined definitions. */
|
|
12
|
+
|
|
13
|
+
class A implements OnInit {
|
|
14
|
+
self = {me: this};
|
|
15
|
+
|
|
16
|
+
constructor(private a: SelectionModel, private b: CdkConnectedOverlay) {}
|
|
17
|
+
|
|
18
|
+
ngOnInit() {
|
|
19
|
+
this.a.changed.subscribe(() => console.log('Changed'));
|
|
20
|
+
this.self.me.a.changed.subscribe(() => console.log('Changed 2'));
|
|
21
|
+
|
|
22
|
+
if (this.b.flexibleDimensions) {
|
|
23
|
+
console.log(this.b.flexibleDimensions ? 'true' : 'false');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const _state = this.self.me.b.flexibleDimensions.toString() || 'not-defined';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {EventEmitter, OnInit} from '@angular/core';
|
|
2
|
+
|
|
3
|
+
class SelectionModel {
|
|
4
|
+
onChange = new EventEmitter<void>();
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class CdkConnectedOverlay {
|
|
8
|
+
flexibleDiemsions: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* Actual test case using the previously defined definitions. */
|
|
12
|
+
|
|
13
|
+
class A implements OnInit {
|
|
14
|
+
self = {me: this};
|
|
15
|
+
|
|
16
|
+
constructor(private a: SelectionModel, private b: CdkConnectedOverlay) {}
|
|
17
|
+
|
|
18
|
+
ngOnInit() {
|
|
19
|
+
this.a.onChange.subscribe(() => console.log('Changed'));
|
|
20
|
+
this.self.me.a.onChange.subscribe(() => console.log('Changed 2'));
|
|
21
|
+
|
|
22
|
+
if (this.b.flexibleDiemsions) {
|
|
23
|
+
console.log(this.b.flexibleDiemsions ? 'true' : 'false');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const _state = this.self.me.b.flexibleDiemsions.toString() || 'not-defined';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as ts from 'typescript';
|
|
10
|
+
|
|
11
|
+
/** Determines the base types of the specified class declaration. */
|
|
12
|
+
export function determineBaseTypes(node: ts.ClassDeclaration): string[] | null {
|
|
13
|
+
if (!node.heritageClauses) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return node.heritageClauses
|
|
18
|
+
.reduce((types, clause) => types.concat(clause.types), [] as ts.ExpressionWithTypeArguments[])
|
|
19
|
+
.map(typeExpression => typeExpression.expression)
|
|
20
|
+
.filter(expression => expression && ts.isIdentifier(expression))
|
|
21
|
+
.map(identifier => (identifier as ts.Identifier).text);
|
|
22
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as ts from 'typescript';
|
|
10
|
+
|
|
11
|
+
/** Checks whether the given node is part of an import specifier node. */
|
|
12
|
+
export function isImportSpecifierNode(node: ts.Node) {
|
|
13
|
+
return isPartOfKind(node, ts.SyntaxKind.ImportSpecifier);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Checks whether the given node is part of an export specifier node. */
|
|
17
|
+
export function isExportSpecifierNode(node: ts.Node) {
|
|
18
|
+
return isPartOfKind(node, ts.SyntaxKind.ExportSpecifier);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Checks whether the given node is part of a namespace import. */
|
|
22
|
+
export function isNamespaceImportNode(node: ts.Node) {
|
|
23
|
+
return isPartOfKind(node, ts.SyntaxKind.NamespaceImport);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Finds the parent import declaration of a given TypeScript node. */
|
|
27
|
+
export function getImportDeclaration(node: ts.Node) {
|
|
28
|
+
return findDeclaration(node, ts.SyntaxKind.ImportDeclaration) as ts.ImportDeclaration;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Finds the parent export declaration of a given TypeScript node */
|
|
32
|
+
export function getExportDeclaration(node: ts.Node) {
|
|
33
|
+
return findDeclaration(node, ts.SyntaxKind.ExportDeclaration) as ts.ExportDeclaration;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Finds the specified declaration for the given node by walking up the TypeScript nodes. */
|
|
37
|
+
function findDeclaration<T extends ts.SyntaxKind>(node: ts.Node, kind: T) {
|
|
38
|
+
while (node.kind !== kind) {
|
|
39
|
+
node = node.parent;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return node;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Checks whether the given node is part of another TypeScript Node with the specified kind. */
|
|
46
|
+
function isPartOfKind<T extends ts.SyntaxKind>(node: ts.Node, kind: T): boolean {
|
|
47
|
+
if (node.kind === kind) {
|
|
48
|
+
return true;
|
|
49
|
+
} else if (node.kind === ts.SyntaxKind.SourceFile) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return isPartOfKind(node.parent, kind);
|
|
54
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as ts from 'typescript';
|
|
10
|
+
|
|
11
|
+
/** Finds all start indices of the given search string in the input string. */
|
|
12
|
+
export function findAllSubstringIndices(input: string, search: string): number[] {
|
|
13
|
+
const result: number[] = [];
|
|
14
|
+
let i = -1;
|
|
15
|
+
while ((i = input.indexOf(search, i + 1)) !== -1) {
|
|
16
|
+
result.push(i);
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Checks whether the given node is either a string literal or a no-substitution template
|
|
23
|
+
* literal. Note that we cannot use `ts.isStringLiteralLike()` because if developers update
|
|
24
|
+
* an outdated project, their TypeScript version is not automatically being updated
|
|
25
|
+
* and therefore could throw because the function is not available yet.
|
|
26
|
+
* https://github.com/Microsoft/TypeScript/commit/8518343dc8762475a5e92c9f80b5c5725bd81796
|
|
27
|
+
*/
|
|
28
|
+
export function isStringLiteralLike(
|
|
29
|
+
node: ts.Node,
|
|
30
|
+
): node is ts.StringLiteral | ts.NoSubstitutionTemplateLiteral {
|
|
31
|
+
return ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node);
|
|
32
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as ts from 'typescript';
|
|
10
|
+
import {getExportDeclaration, getImportDeclaration} from '../typescript/imports';
|
|
11
|
+
|
|
12
|
+
/** Name of the Angular Material module specifier. */
|
|
13
|
+
export const materialModuleSpecifier = '@dugararchit/material';
|
|
14
|
+
|
|
15
|
+
/** Name of the Angular CDK module specifier. */
|
|
16
|
+
export const cdkModuleSpecifier = '@dugararchit/cdk';
|
|
17
|
+
|
|
18
|
+
/** Whether the specified node is part of an Angular Material or CDK import declaration. */
|
|
19
|
+
export function isMaterialImportDeclaration(node: ts.Node) {
|
|
20
|
+
return isMaterialDeclaration(getImportDeclaration(node));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Whether the specified node is part of an Angular Material or CDK import declaration. */
|
|
24
|
+
export function isMaterialExportDeclaration(node: ts.Node) {
|
|
25
|
+
return isMaterialDeclaration(getExportDeclaration(node));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Whether the declaration is part of Angular Material. */
|
|
29
|
+
function isMaterialDeclaration(declaration: ts.ImportDeclaration | ts.ExportDeclaration) {
|
|
30
|
+
if (!declaration.moduleSpecifier) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const moduleSpecifier = declaration.moduleSpecifier.getText();
|
|
35
|
+
return (
|
|
36
|
+
moduleSpecifier.indexOf(materialModuleSpecifier) !== -1 ||
|
|
37
|
+
moduleSpecifier.indexOf(cdkModuleSpecifier) !== -1
|
|
38
|
+
);
|
|
39
|
+
}
|