ng-configcat-publicapi-ui 3.0.8 → 4.0.0

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.
Files changed (136) hide show
  1. package/esm2022/lib/_directives/input-display-normalizer.directive.mjs +38 -0
  2. package/esm2022/lib/_models/flag-state.mjs +2 -0
  3. package/esm2022/lib/_models/setting-value-formgroup.mjs +2 -0
  4. package/esm2022/lib/_models/user-comparator.mjs +100 -0
  5. package/esm2022/lib/_services/app-data-adapter.mjs +18 -0
  6. package/esm2022/lib/_services/comparison-value-list-helper.mjs +72 -0
  7. package/esm2022/lib/_services/date-helper.mjs +56 -0
  8. package/esm2022/lib/_services/form-generator.mjs +359 -0
  9. package/esm2022/lib/_services/form-helper.mjs +107 -0
  10. package/esm2022/lib/_services/messaging.service.mjs +26 -0
  11. package/esm2022/lib/_services/public-api.service.mjs +77 -0
  12. package/esm2022/lib/_services/setting-list-form-helper.mjs +171 -0
  13. package/esm2022/lib/_services/tracking.directive.mjs +16 -0
  14. package/esm2022/lib/ace-editor/ace-editor.component.mjs +137 -0
  15. package/esm2022/lib/authorization/authorization.component.mjs +62 -0
  16. package/{esm2020 → esm2022}/lib/base/base-select.component.mjs +4 -4
  17. package/esm2022/lib/base/base.component.mjs +48 -0
  18. package/esm2022/lib/bootstrap.mjs +10 -0
  19. package/{esm2020 → esm2022}/lib/configuration.mjs +4 -4
  20. package/esm2022/lib/dialogs/confirmation-dialog/confirmation-dialog.mjs +28 -0
  21. package/{esm2020 → esm2022}/lib/dialogs/delete-setting-dialog/delete-setting-dialog.component.mjs +6 -6
  22. package/esm2022/lib/dialogs/expand-dialog/expand-dialog.component.mjs +80 -0
  23. package/esm2022/lib/dialogs/info-dialog/info-dialog.mjs +29 -0
  24. package/esm2022/lib/dialogs/reason-dialog/reason-dialog.component.mjs +36 -0
  25. package/{esm2020 → esm2022}/lib/dialogs/save-snackbar/save-snackbar.component.mjs +5 -5
  26. package/esm2022/lib/ng-configcat-publicapi-ui.module.mjs +285 -0
  27. package/esm2022/lib/selects/config-select/config-select.component.mjs +60 -0
  28. package/esm2022/lib/selects/environment-select/environment-select.component.mjs +47 -0
  29. package/esm2022/lib/selects/product-select/product-select.component.mjs +40 -0
  30. package/esm2022/lib/selects/setting-select/setting-select.component.mjs +47 -0
  31. package/esm2022/lib/setting-item/setting-item.component.mjs +118 -0
  32. package/esm2022/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +81 -0
  33. package/esm2022/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +293 -0
  34. package/{esm2020 → esm2022}/lib/setting-list/setting/setting.component.mjs +5 -5
  35. package/esm2022/lib/setting-list/setting/value/value.component.mjs +37 -0
  36. package/esm2022/lib/setting-list/setting-list.component.mjs +194 -0
  37. package/esm2022/lib/v2/feature-flag/date-time-picker/date-time-picker.component.mjs +123 -0
  38. package/esm2022/lib/v2/feature-flag/dependees-dialog/dependees-dialog.component.mjs +30 -0
  39. package/esm2022/lib/v2/feature-flag/evaluation-formula/evaluation-formula.component.mjs +220 -0
  40. package/esm2022/lib/v2/feature-flag/evaluation-formula/feature-flag-value/feature-flag-value.component.mjs +61 -0
  41. package/esm2022/lib/v2/feature-flag/evaluation-formula/popout-text-editor-dialog/popout-text-editor-dialog.component.mjs +72 -0
  42. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/condition-chip/condition-chip.component.mjs +25 -0
  43. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/conditions.component.mjs +105 -0
  44. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/prerequisite-flag-condition/prerequisite-flag-condition.component.mjs +75 -0
  45. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/segment-condition/segment-condition.component.mjs +48 -0
  46. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/comparator-dialog/comparator-dialog.component.mjs +113 -0
  47. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/popout-list-editor-dialog/popout-list-editor-dialog.component.mjs +251 -0
  48. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/user-condition.component.mjs +444 -0
  49. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/percentage-options/percentage-options.component.mjs +84 -0
  50. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/targeting-rule.component.mjs +129 -0
  51. package/esm2022/lib/v2/feature-flag/feature-flag.component.mjs +190 -0
  52. package/esm2022/lib/v2/feature-flag/percentage-evaluation-attribute-dialog/percentage-evaluation-attribute-dialog.component.mjs +65 -0
  53. package/esm2022/lib/v2/feature-flag-item.component.mjs +319 -0
  54. package/{esm2020 → esm2022}/public-api.mjs +2 -1
  55. package/fesm2022/ng-configcat-publicapi-ui.mjs +4790 -0
  56. package/fesm2022/ng-configcat-publicapi-ui.mjs.map +1 -0
  57. package/lib/_models/flag-state.d.ts +20 -0
  58. package/lib/_models/setting-value-formgroup.d.ts +69 -0
  59. package/lib/_models/user-comparator.d.ts +84 -0
  60. package/lib/_services/app-data-adapter.d.ts +7 -0
  61. package/lib/_services/comparison-value-list-helper.d.ts +17 -0
  62. package/lib/_services/date-helper.d.ts +6 -0
  63. package/lib/_services/form-generator.d.ts +59 -0
  64. package/lib/_services/form-helper.d.ts +4 -1
  65. package/lib/_services/messaging.service.d.ts +12 -0
  66. package/lib/_services/public-api.service.d.ts +2 -1
  67. package/lib/_services/setting-list-form-helper.d.ts +1 -1
  68. package/lib/_services/tracking.directive.d.ts +6 -0
  69. package/lib/ace-editor/ace-editor.component.d.ts +32 -0
  70. package/lib/authorization/authorization.component.d.ts +2 -2
  71. package/lib/base/base-select.component.d.ts +1 -1
  72. package/lib/base/base.component.d.ts +2 -1
  73. package/lib/bootstrap.d.ts +12 -0
  74. package/lib/dialogs/confirmation-dialog/confirmation-dialog.d.ts +19 -0
  75. package/lib/dialogs/info-dialog/info-dialog.d.ts +17 -0
  76. package/lib/ng-configcat-publicapi-ui.module.d.ts +47 -19
  77. package/lib/selects/config-select/config-select.component.d.ts +1 -1
  78. package/lib/selects/environment-select/environment-select.component.d.ts +1 -1
  79. package/lib/selects/product-select/product-select.component.d.ts +1 -1
  80. package/lib/selects/setting-select/setting-select.component.d.ts +1 -1
  81. package/lib/setting-item/setting-item.component.d.ts +4 -2
  82. package/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.d.ts +1 -1
  83. package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +4 -4
  84. package/lib/setting-list/setting/setting.component.d.ts +1 -1
  85. package/lib/setting-list/setting/value/value.component.d.ts +1 -1
  86. package/lib/setting-list/setting-list.component.d.ts +1 -1
  87. package/lib/v2/feature-flag/date-time-picker/date-time-picker.component.d.ts +25 -0
  88. package/lib/v2/feature-flag/dependees-dialog/dependees-dialog.component.d.ts +27 -0
  89. package/lib/v2/feature-flag/evaluation-formula/evaluation-formula.component.d.ts +41 -0
  90. package/lib/v2/feature-flag/evaluation-formula/feature-flag-value/feature-flag-value.component.d.ts +18 -0
  91. package/lib/v2/feature-flag/evaluation-formula/popout-text-editor-dialog/popout-text-editor-dialog.component.d.ts +30 -0
  92. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/condition-chip/condition-chip.component.d.ts +10 -0
  93. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/conditions.component.d.ts +27 -0
  94. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/prerequisite-flag-condition/prerequisite-flag-condition.component.d.ts +36 -0
  95. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/segment-condition/segment-condition.component.d.ts +21 -0
  96. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/comparator-dialog/comparator-dialog.component.d.ts +79 -0
  97. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/popout-list-editor-dialog/popout-list-editor-dialog.component.d.ts +63 -0
  98. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/user-condition.component.d.ts +94 -0
  99. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/percentage-options/percentage-options.component.d.ts +31 -0
  100. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/targeting-rule.component.d.ts +33 -0
  101. package/lib/v2/feature-flag/feature-flag.component.d.ts +49 -0
  102. package/lib/v2/feature-flag/percentage-evaluation-attribute-dialog/percentage-evaluation-attribute-dialog.component.d.ts +28 -0
  103. package/lib/v2/feature-flag-item.component.d.ts +66 -0
  104. package/package.json +12 -16
  105. package/public-api.d.ts +1 -0
  106. package/public-api.scss +205 -3
  107. package/esm2020/lib/_directives/input-display-normalizer.directive.mjs +0 -38
  108. package/esm2020/lib/_services/form-helper.mjs +0 -104
  109. package/esm2020/lib/_services/public-api.service.mjs +0 -71
  110. package/esm2020/lib/_services/setting-list-form-helper.mjs +0 -171
  111. package/esm2020/lib/authorization/authorization.component.mjs +0 -62
  112. package/esm2020/lib/base/base.component.mjs +0 -45
  113. package/esm2020/lib/dialogs/expand-dialog/expand-dialog.component.mjs +0 -80
  114. package/esm2020/lib/dialogs/reason-dialog/reason-dialog.component.mjs +0 -36
  115. package/esm2020/lib/ng-configcat-publicapi-ui.module.mjs +0 -179
  116. package/esm2020/lib/selects/config-select/config-select.component.mjs +0 -60
  117. package/esm2020/lib/selects/environment-select/environment-select.component.mjs +0 -47
  118. package/esm2020/lib/selects/product-select/product-select.component.mjs +0 -40
  119. package/esm2020/lib/selects/setting-select/setting-select.component.mjs +0 -47
  120. package/esm2020/lib/setting-item/setting-item.component.mjs +0 -116
  121. package/esm2020/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +0 -81
  122. package/esm2020/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +0 -293
  123. package/esm2020/lib/setting-list/setting/value/value.component.mjs +0 -37
  124. package/esm2020/lib/setting-list/setting-list.component.mjs +0 -194
  125. package/fesm2015/ng-configcat-publicapi-ui.mjs +0 -1786
  126. package/fesm2015/ng-configcat-publicapi-ui.mjs.map +0 -1
  127. package/fesm2020/ng-configcat-publicapi-ui.mjs +0 -1763
  128. package/fesm2020/ng-configcat-publicapi-ui.mjs.map +0 -1
  129. /package/{esm2020 → esm2022}/lib/_directives/index.mjs +0 -0
  130. /package/{esm2020 → esm2022}/lib/_models/deleteSettingModel.mjs +0 -0
  131. /package/{esm2020 → esm2022}/lib/_models/index.mjs +0 -0
  132. /package/{esm2020 → esm2022}/lib/_models/settingValuesModel.mjs +0 -0
  133. /package/{esm2020 → esm2022}/lib/_models/updateSettingValuesModel.mjs +0 -0
  134. /package/{esm2020 → esm2022}/lib/_services/index.mjs +0 -0
  135. /package/{esm2020 → esm2022}/lib/_services/platform-helper.mjs +0 -0
  136. /package/{esm2020 → esm2022}/ng-configcat-publicapi-ui.mjs +0 -0
@@ -0,0 +1,49 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { FormGroup } from '@angular/forms';
3
+ import { MatDialog } from '@angular/material/dialog';
4
+ import { MessagingService, ISegment, IPrerequisiteChanged, IFeatureFlagLimitations, UpdateSettingValueForm, FormGenerator, IFlagState } from '../../bootstrap';
5
+ import { Router } from '@angular/router';
6
+ import { PublicApiService } from '../../_services';
7
+ import { Clipboard } from '@angular/cdk/clipboard';
8
+ import * as i0 from "@angular/core";
9
+ export interface IGlance {
10
+ ruleText: string;
11
+ percentageText: string;
12
+ class: string;
13
+ }
14
+ export declare class FeatureFlagComponent {
15
+ private dialog;
16
+ private messagingService;
17
+ private formGenerator;
18
+ private router;
19
+ private publicApiService;
20
+ private clipboard;
21
+ formGroup: FormGroup<UpdateSettingValueForm>;
22
+ flagState: IFlagState;
23
+ segments: ISegment[];
24
+ featureFlagLimitations: IFeatureFlagLimitations;
25
+ hasOtherEnvironment: boolean;
26
+ environmentName: string;
27
+ showEnvironmentName: boolean;
28
+ deleteSettingText: string;
29
+ addSegmentConditionRequestedWithoutSegments: EventEmitter<any>;
30
+ expandedChanged: EventEmitter<boolean>;
31
+ deleteSettingRequested: EventEmitter<any>;
32
+ subscriptionLimitReached: EventEmitter<any>;
33
+ prerequisiteConditionChanged: EventEmitter<IPrerequisiteChanged>;
34
+ recalcAddButtons: EventEmitter<any>;
35
+ constructor(dialog: MatDialog, messagingService: MessagingService, formGenerator: FormGenerator, router: Router, publicApiService: PublicApiService, clipboard: Clipboard);
36
+ setExpanded(expanded: boolean): void;
37
+ deleteSetting(): void;
38
+ keyCopied(): void;
39
+ subscriptionLimitReachedCalled(): void;
40
+ changePercentageEvaluationAttribute(): void;
41
+ getGlance(): IGlance;
42
+ getRuleText(): string;
43
+ openInConfigCat(): void;
44
+ copyDirectLink(): void;
45
+ getDashboardUrl(): string;
46
+ openDependeesDialog(): void;
47
+ static ɵfac: i0.ɵɵFactoryDeclaration<FeatureFlagComponent, never>;
48
+ static ɵcmp: i0.ɵɵComponentDeclaration<FeatureFlagComponent, "app-feature-flag", never, { "formGroup": { "alias": "formGroup"; "required": false; }; "flagState": { "alias": "flagState"; "required": false; }; "segments": { "alias": "segments"; "required": false; }; "featureFlagLimitations": { "alias": "featureFlagLimitations"; "required": false; }; "hasOtherEnvironment": { "alias": "hasOtherEnvironment"; "required": false; }; "environmentName": { "alias": "environmentName"; "required": false; }; "showEnvironmentName": { "alias": "showEnvironmentName"; "required": false; }; "deleteSettingText": { "alias": "deleteSettingText"; "required": false; }; }, { "addSegmentConditionRequestedWithoutSegments": "addSegmentConditionRequestedWithoutSegments"; "expandedChanged": "expandedChanged"; "deleteSettingRequested": "deleteSettingRequested"; "subscriptionLimitReached": "subscriptionLimitReached"; "prerequisiteConditionChanged": "prerequisiteConditionChanged"; "recalcAddButtons": "recalcAddButtons"; }, never, never, false, never>;
49
+ }
@@ -0,0 +1,28 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { FormControl } from '@angular/forms';
3
+ import { MatDialogRef } from '@angular/material/dialog';
4
+ import { FormHelper, FormGenerator } from '../../../bootstrap';
5
+ import * as i0 from "@angular/core";
6
+ export declare class PercentageEvaluationAttributeDialogComponent implements OnInit {
7
+ dialogRef: MatDialogRef<PercentageEvaluationAttributeDialogComponent>;
8
+ private formGenerator;
9
+ data: {
10
+ percentageEvaluationAttribute: string;
11
+ readOnly: boolean;
12
+ };
13
+ FormHelper: typeof FormHelper;
14
+ readOnly: boolean;
15
+ defaultComparisonAttributes: string[];
16
+ formControl: FormControl<string>;
17
+ constructor(dialogRef: MatDialogRef<PercentageEvaluationAttributeDialogComponent>, formGenerator: FormGenerator, data: {
18
+ percentageEvaluationAttribute: string;
19
+ readOnly: boolean;
20
+ });
21
+ ngOnInit(): void;
22
+ close(): void;
23
+ attributeChanged(event: Event): void;
24
+ isDefault(attribute: string): boolean;
25
+ set(): void;
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<PercentageEvaluationAttributeDialogComponent, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<PercentageEvaluationAttributeDialogComponent, "app-percentage-evaluation-attribute-dialog", never, {}, {}, never, never, false, never>;
28
+ }
@@ -0,0 +1,66 @@
1
+ import { OnInit, EventEmitter, OnDestroy } from '@angular/core';
2
+ import { BaseComponent } from '../base/base.component';
3
+ import { SegmentListModel, SettingDataModel, SettingFormulaModel, UpdateEvaluationFormulaModel } from 'ng-configcat-publicapi';
4
+ import { IFlagState } from '../_models/flag-state';
5
+ import { FormGroup } from '@angular/forms';
6
+ import { IPrerequisiteSetting, UpdateSettingValueForm } from '../_models/setting-value-formgroup';
7
+ import { PublicApiService } from '../_services';
8
+ import { Subscription } from 'rxjs';
9
+ import { FormGenerator } from '../_services/form-generator';
10
+ import { MatDialog } from '@angular/material/dialog';
11
+ import { MatSnackBar } from '@angular/material/snack-bar';
12
+ import * as i0 from "@angular/core";
13
+ export declare class FeatureFlagItemComponent extends BaseComponent implements OnInit, OnDestroy {
14
+ private formGenerator;
15
+ private dialog;
16
+ private snackBar;
17
+ productId: string;
18
+ environmentId: string;
19
+ configId: string;
20
+ settingId: number;
21
+ canDeleteSetting: boolean;
22
+ deleteSettingText: string;
23
+ showEnvironmentName: boolean;
24
+ deleteSettingRequested: EventEmitter<any>;
25
+ loadSucceeded: EventEmitter<any>;
26
+ loadFailed: EventEmitter<any>;
27
+ saveSucceeded: EventEmitter<any>;
28
+ saveFailed: EventEmitter<any>;
29
+ expandedStateChanged: EventEmitter<any>;
30
+ formValuesChanged: EventEmitter<any>;
31
+ segments: SegmentListModel[];
32
+ dashboardBasePath: string;
33
+ loading: boolean;
34
+ formGroup: FormGroup<UpdateSettingValueForm>;
35
+ formValueChangesSubscription: Subscription;
36
+ settings: SettingDataModel[];
37
+ flagState: IFlagState;
38
+ settingFormula: SettingFormulaModel;
39
+ prerequisiteSettings: IPrerequisiteSetting[];
40
+ showFeedBackMessage: boolean;
41
+ hasSettingValues: boolean;
42
+ hasOtherEnvironment: boolean;
43
+ constructor(formGenerator: FormGenerator, dialog: MatDialog, snackBar: MatSnackBar, publicApiService: PublicApiService);
44
+ ngOnInit(): void;
45
+ ngOnDestroy(): void;
46
+ reloadSettingValues(): void;
47
+ handleFetchedSettingValues(model: SettingFormulaModel): void;
48
+ unsubscribeFormValueChangesSubscription(): void;
49
+ private createFormGroupFromState;
50
+ getAvailablePrerequisiteSettings(settingId: number): IPrerequisiteSetting[];
51
+ revert(): void;
52
+ revertDirtyValuesFromState(): void;
53
+ submit(): void;
54
+ updateSettingValues(updateModel: UpdateEvaluationFormulaModel, reason?: string): void;
55
+ onDeleteSettingRequested(setting: any): void;
56
+ private deleteSettingInternal;
57
+ subscriptionLimitReachedCalled(): void;
58
+ addSegmentConditionRequestedWithoutSegments(): void;
59
+ trackByIndex(index: number): any;
60
+ recalcPrerequisites(): void;
61
+ recalcAddButtons(): void;
62
+ hasOnlyPercentageRule(group: FormGroup<UpdateSettingValueForm>): boolean;
63
+ expandedChanged(expandedState: boolean): void;
64
+ static ɵfac: i0.ɵɵFactoryDeclaration<FeatureFlagItemComponent, never>;
65
+ static ɵcmp: i0.ɵɵComponentDeclaration<FeatureFlagItemComponent, "configcat-feature-flag-item", never, { "productId": { "alias": "productId"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "configId": { "alias": "configId"; "required": false; }; "settingId": { "alias": "settingId"; "required": false; }; "canDeleteSetting": { "alias": "canDeleteSetting"; "required": false; }; "deleteSettingText": { "alias": "deleteSettingText"; "required": false; }; "showEnvironmentName": { "alias": "showEnvironmentName"; "required": false; }; }, { "deleteSettingRequested": "deleteSettingRequested"; "loadSucceeded": "loadSucceeded"; "loadFailed": "loadFailed"; "saveSucceeded": "saveSucceeded"; "saveFailed": "saveFailed"; "expandedStateChanged": "expandedStateChanged"; "formValuesChanged": "formValuesChanged"; }, never, never, false, never>;
66
+ }
package/package.json CHANGED
@@ -1,20 +1,18 @@
1
1
  {
2
2
  "name": "ng-configcat-publicapi-ui",
3
- "version": "3.0.8",
3
+ "version": "4.0.0",
4
4
  "peerDependencies": {
5
- "@angular/common": "^15.2.10",
6
- "@angular/core": "^15.2.10",
7
- "ng-configcat-publicapi": "^4.1.2",
8
- "semver": "^7.5.3"
5
+ "@angular/common": "^17.1.3",
6
+ "@angular/core": "^17.1.3",
7
+ "ng-configcat-publicapi": "^4.3.0",
8
+ "semver": "^7.5.3",
9
+ "papaparse": "^5.4.1",
10
+ "ace-builds": "^1.31.0"
9
11
  },
10
12
  "dependencies": {
11
- "tslib": "^2.3.0"
13
+ "tslib": "^2.4.0"
12
14
  },
13
- "module": "fesm2015/ng-configcat-publicapi-ui.mjs",
14
- "es2020": "fesm2020/ng-configcat-publicapi-ui.mjs",
15
- "esm2020": "esm2020/ng-configcat-publicapi-ui.mjs",
16
- "fesm2020": "fesm2020/ng-configcat-publicapi-ui.mjs",
17
- "fesm2015": "fesm2015/ng-configcat-publicapi-ui.mjs",
15
+ "module": "fesm2022/ng-configcat-publicapi-ui.mjs",
18
16
  "typings": "index.d.ts",
19
17
  "exports": {
20
18
  "./package.json": {
@@ -22,11 +20,9 @@
22
20
  },
23
21
  ".": {
24
22
  "types": "./index.d.ts",
25
- "esm2020": "./esm2020/ng-configcat-publicapi-ui.mjs",
26
- "es2020": "./fesm2020/ng-configcat-publicapi-ui.mjs",
27
- "es2015": "./fesm2015/ng-configcat-publicapi-ui.mjs",
28
- "node": "./fesm2015/ng-configcat-publicapi-ui.mjs",
29
- "default": "./fesm2020/ng-configcat-publicapi-ui.mjs"
23
+ "esm2022": "./esm2022/ng-configcat-publicapi-ui.mjs",
24
+ "esm": "./esm2022/ng-configcat-publicapi-ui.mjs",
25
+ "default": "./fesm2022/ng-configcat-publicapi-ui.mjs"
30
26
  }
31
27
  },
32
28
  "sideEffects": false
package/public-api.d.ts CHANGED
@@ -8,3 +8,4 @@ export * from './lib/selects/config-select/config-select.component';
8
8
  export * from './lib/selects/environment-select/environment-select.component';
9
9
  export * from './lib/selects/setting-select/setting-select.component';
10
10
  export * from './lib/dialogs/delete-setting-dialog/delete-setting-dialog.component';
11
+ export * from './lib/v2/feature-flag-item.component';
package/public-api.scss CHANGED
@@ -1,5 +1,4 @@
1
1
  @use '@angular/material' as mat;
2
- @import '@angular/material/theming';
3
2
 
4
3
  @include mat.core();
5
4
 
@@ -33,8 +32,8 @@ html[data-color-mode='dark'] {
33
32
 
34
33
  select {
35
34
  color: #000;
36
-
37
- option{
35
+
36
+ option {
38
37
  color: #000;
39
38
  }
40
39
  }
@@ -69,6 +68,37 @@ html {
69
68
  color: inherit;
70
69
  }
71
70
 
71
+ .mdc-notched-outline__notch {
72
+ border-left: none !important;
73
+ }
74
+
75
+ .mdc-notched-outline>* {
76
+ border-color: #dbdbdb !important;
77
+ }
78
+
79
+ .mdc-text-field--focused .mdc-notched-outline>* {
80
+ border-color: #f7a224 !important;
81
+ }
82
+
83
+ .mdc-text-field--invalid .mdc-notched-outline>* {
84
+ border-color: red !important;
85
+ }
86
+
87
+ .mat-mdc-outlined-button.mat-primary {
88
+ color: #e78b00;
89
+ }
90
+
91
+ .component .mat-mdc-text-field-wrapper,
92
+ .targeting-rule-component .mat-mdc-text-field-wrapper {
93
+ background-color: rgb(255, 255, 255);
94
+ border-bottom-left-radius: 4px;
95
+ border-bottom-right-radius: 4px;
96
+ }
97
+
98
+ .mat-button-toggle-label-content {
99
+ line-height: 34px !important;
100
+ }
101
+
72
102
  .mat-mdc-tooltip {
73
103
  font-size: 14px !important;
74
104
  white-space: pre-line;
@@ -85,6 +115,23 @@ html {
85
115
  }
86
116
  }
87
117
 
118
+ .mat-mdc-optgroup {
119
+ .mdc-list-item__primary-text {
120
+ font-size: 14px;
121
+ line-height: 24px;
122
+ }
123
+ }
124
+
125
+ .mat-mdc-optgroup .mat-mdc-option:not(.mat-mdc-option-multiple) {
126
+ padding-left: 24px;
127
+ }
128
+
129
+ .mat-mdc-dialog-title.draggable {
130
+ cursor: grab;
131
+ cursor: -moz-grab;
132
+ cursor: -webkit-grab;
133
+ }
134
+
88
135
  .mat-mdc-form-field {
89
136
 
90
137
  .mat-mdc-form-field-hint-wrapper,
@@ -100,6 +147,10 @@ html {
100
147
  }
101
148
  }
102
149
 
150
+ .mat-mdc-standard-chip .mdc-evolution-chip__text-label {
151
+ font-size: 12px;
152
+ }
153
+
103
154
  .mat-mdc-select-panel.custom-dropdown-below {
104
155
  position: absolute;
105
156
  }
@@ -110,6 +161,157 @@ html {
110
161
  white-space: nowrap;
111
162
  }
112
163
 
164
+ .hide-menu-overflow-text {
165
+ .mat-mdc-menu-item-text {
166
+ max-width: 100%;
167
+ overflow: hidden;
168
+ text-overflow: ellipsis;
169
+ }
170
+ }
171
+
172
+ .menu-long-text-or {
173
+ min-width: 370px;
174
+ }
175
+
176
+ .menu-long-text-and {
177
+ min-width: 300px;
178
+ }
179
+
180
+ .menu-with-icon {
181
+ .mat-mdc-menu-item-text {
182
+ max-width: 90%;
183
+ }
184
+ }
185
+
186
+ .mat-mdc-menu-content {
187
+ font-size: 14px !important;
188
+
189
+ .mat-mdc-menu-item {
190
+ font-size: 14px !important;
191
+ vertical-align: middle !important;
192
+ min-height: 38px !important;
193
+ line-height: 38px !important;
194
+ padding: 0 20px 0 16px !important;
195
+
196
+ .mat-icon {
197
+ font-size: 18px !important;
198
+ height: 18px !important;
199
+ width: 18px !important;
200
+ margin-right: 8px !important;
201
+ color: rgba(0, 0, 0, 0.54);
202
+ }
203
+
204
+ .mat-mdc-menu-ripple {
205
+ height: 38px !important;
206
+ min-height: 38px !important;
207
+ }
208
+
209
+ &[disabled] {
210
+ pointer-events: none;
211
+ }
212
+ }
213
+ }
214
+
215
+ .mat-mdc-table {
216
+ border-bottom: solid 1px rgba(0, 0, 0, 0.12) !important;
217
+
218
+ .mat-mdc-cell,
219
+ .mat-mdc-header-cell {
220
+ padding-left: 8px !important;
221
+ padding-right: 8px !important;
222
+ font-size: 12px !important;
223
+ line-height: normal !important;
224
+ }
225
+ }
226
+
227
+ .mat-mdc-form-field-type-mat-select.mat-form-field-appearance-outline .mdc-notched-outline__notch {
228
+ max-width: inherit;
229
+ }
230
+
231
+ .mat-mdc-select-panel.long-panel {
232
+ max-height: 72vh !important;
233
+
234
+ .mdc-list-item__primary-text {
235
+ overflow: hidden;
236
+ text-overflow: ellipsis;
237
+ }
238
+ }
239
+
240
+ .mat-mdc-tab-group {
241
+ .mat-mdc-tab-header {
242
+ border-bottom: 1px solid rgba(0, 0, 0, .12);
243
+ }
244
+
245
+ &.small-header {
246
+ .mat-mdc-tab {
247
+ min-width: 64px !important;
248
+ padding: 0 3px !important;
249
+ margin: 0 3px !important;
250
+ }
251
+ }
252
+ }
253
+
254
+
255
+ .small-form-field {
256
+ @include mat.form-field-density(-5);
257
+ }
258
+
259
+ .smallest-form-field {
260
+ @include mat.form-field-density(-5);
261
+
262
+ .mat-mdc-form-field-infix {
263
+ padding-top: 4px !important;
264
+ padding-bottom: 4px !important;
265
+ min-height: 32px !important;
266
+ }
267
+ }
268
+
269
+ .small-icon-button {
270
+ @include mat.icon-button-density(-5);
271
+
272
+ .mat-icon {
273
+ padding: 0 6px;
274
+ }
275
+
276
+ .mat-mdc-icon-button {
277
+ .mat-icon {
278
+ padding: 0 0;
279
+ }
280
+ }
281
+ }
282
+
283
+ .small-chip-input {
284
+ .chip-container {
285
+ min-width: 0;
286
+ }
287
+
288
+ .mdc-evolution-chip-set .mdc-evolution-chip {
289
+ margin-top: 1px;
290
+ margin-bottom: 1px;
291
+ margin-left: 4px;
292
+ height: 22px;
293
+
294
+ .mdc-evolution-chip__cell--primary,
295
+ .mdc-evolution-chip__action--primary,
296
+ .mat-mdc-chip-action-label {
297
+ white-space: nowrap;
298
+ overflow: hidden;
299
+ text-overflow: ellipsis;
300
+ }
301
+ }
302
+ }
303
+
304
+ .top-icon-suffix {
305
+ .mat-mdc-form-field-icon-suffix {
306
+ align-self: start;
307
+ padding-top: 4px;
308
+ }
309
+
310
+ .mat-mdc-form-field-icon-prefix {
311
+ align-self: start;
312
+ padding-top: 6px;
313
+ }
314
+ }
113
315
  }
114
316
  }
115
317
 
@@ -1,38 +0,0 @@
1
- import { Directive, HostListener } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- /**
4
- * Makes sure that values entered into HTML input fields are displayed in the correct format,
5
- * where correct means normalized (e.g. `'.10'` --> `'0.1'`) and corresponding to the locale setting.
6
- *
7
- * The format is adjusted on the blur event. Only the format of number inputs is adjusted currently.
8
- */
9
- export class InputDisplayNormalizerDirective {
10
- constructor() { }
11
- onChange($event) {
12
- const target = $event.target;
13
- if (target.type === 'number') {
14
- let value = target.value;
15
- value = value.trim() !== '' ? Number(value) : NaN;
16
- if (isFinite(value)) {
17
- // The string returned by the `value` property and the string displayed in the input field are not necessarily equal.
18
- // HACK: When the returned and the displayed value differs only in the decimal separator,
19
- // Chrome won't update the displayed value unless the value is changed first...
20
- target.value = '';
21
- target.value = value;
22
- }
23
- }
24
- }
25
- }
26
- InputDisplayNormalizerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDisplayNormalizerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
27
- InputDisplayNormalizerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]", host: { listeners: { "blur": "onChange($event)" } }, ngImport: i0 });
28
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDisplayNormalizerDirective, decorators: [{
29
- type: Directive,
30
- args: [{
31
- // eslint-disable-next-line @angular-eslint/directive-selector
32
- selector: 'input[inputDisplayNormalizer]'
33
- }]
34
- }], ctorParameters: function () { return []; }, propDecorators: { onChange: [{
35
- type: HostListener,
36
- args: ['blur', ['$event']]
37
- }] } });
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZGlzcGxheS1ub3JtYWxpemVyLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWNvbmZpZ2NhdC1wdWJsaWNhcGktdWkvc3JjL2xpYi9fZGlyZWN0aXZlcy9pbnB1dC1kaXNwbGF5LW5vcm1hbGl6ZXIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUV4RDs7Ozs7R0FLRztBQUtILE1BQU0sT0FBTywrQkFBK0I7SUFDeEMsZ0JBQWdCLENBQUM7SUFHakIsUUFBUSxDQUFDLE1BQVc7UUFDaEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUM3QixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1lBQzFCLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFDekIsS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ2xELElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUNqQixxSEFBcUg7Z0JBQ3JILHlGQUF5RjtnQkFDekYsK0VBQStFO2dCQUMvRSxNQUFNLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDbEIsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7YUFDeEI7U0FDSjtJQUNMLENBQUM7OzZIQWpCUSwrQkFBK0I7aUhBQS9CLCtCQUErQjs0RkFBL0IsK0JBQStCO2tCQUozQyxTQUFTO21CQUFDO29CQUNQLDhEQUE4RDtvQkFDOUQsUUFBUSxFQUFFLCtCQUErQjtpQkFDNUM7MEVBS0csUUFBUTtzQkFEUCxZQUFZO3VCQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogTWFrZXMgc3VyZSB0aGF0IHZhbHVlcyBlbnRlcmVkIGludG8gSFRNTCBpbnB1dCBmaWVsZHMgYXJlIGRpc3BsYXllZCBpbiB0aGUgY29ycmVjdCBmb3JtYXQsXG4gKiB3aGVyZSBjb3JyZWN0IG1lYW5zIG5vcm1hbGl6ZWQgKGUuZy4gYCcuMTAnYCAtLT4gYCcwLjEnYCkgYW5kIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGxvY2FsZSBzZXR0aW5nLlxuICogXG4gKiBUaGUgZm9ybWF0IGlzIGFkanVzdGVkIG9uIHRoZSBibHVyIGV2ZW50LiBPbmx5IHRoZSBmb3JtYXQgb2YgbnVtYmVyIGlucHV0cyBpcyBhZGp1c3RlZCBjdXJyZW50bHkuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yXG4gICAgc2VsZWN0b3I6ICdpbnB1dFtpbnB1dERpc3BsYXlOb3JtYWxpemVyXSdcbn0pXG5leHBvcnQgY2xhc3MgSW5wdXREaXNwbGF5Tm9ybWFsaXplckRpcmVjdGl2ZSB7XG4gICAgY29uc3RydWN0b3IoKSB7IH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ2JsdXInLCBbJyRldmVudCddKVxuICAgIG9uQ2hhbmdlKCRldmVudDogYW55KSB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9ICRldmVudC50YXJnZXQ7XG4gICAgICAgIGlmICh0YXJnZXQudHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IHRhcmdldC52YWx1ZTtcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpICE9PSAnJyA/IE51bWJlcih2YWx1ZSkgOiBOYU47XG4gICAgICAgICAgICBpZiAoaXNGaW5pdGUodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgYHZhbHVlYCBwcm9wZXJ0eSBhbmQgdGhlIHN0cmluZyBkaXNwbGF5ZWQgaW4gdGhlIGlucHV0IGZpZWxkIGFyZSBub3QgbmVjZXNzYXJpbHkgZXF1YWwuXG4gICAgICAgICAgICAgICAgLy8gSEFDSzogV2hlbiB0aGUgcmV0dXJuZWQgYW5kIHRoZSBkaXNwbGF5ZWQgdmFsdWUgZGlmZmVycyBvbmx5IGluIHRoZSBkZWNpbWFsIHNlcGFyYXRvcixcbiAgICAgICAgICAgICAgICAvLyBDaHJvbWUgd29uJ3QgdXBkYXRlIHRoZSBkaXNwbGF5ZWQgdmFsdWUgdW5sZXNzIHRoZSB2YWx1ZSBpcyBjaGFuZ2VkIGZpcnN0Li4uXG4gICAgICAgICAgICAgICAgdGFyZ2V0LnZhbHVlID0gJyc7XG4gICAgICAgICAgICAgICAgdGFyZ2V0LnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59Il19
@@ -1,104 +0,0 @@
1
- import { HttpErrorResponse } from '@angular/common/http';
2
- import { PlatformHelper } from './platform-helper';
3
- export class FormHelper {
4
- static getErrorMessage(control, hint = '') {
5
- if (!control || control.valid) {
6
- return;
7
- }
8
- if (control.hasError('required')) {
9
- return `${hint} The field is required.`;
10
- }
11
- if (control.hasError('pattern')) {
12
- return 'Not a valid e-mail address.';
13
- }
14
- if (control.hasError('minlength')) {
15
- return 'The field must be at least ' + control.getError('minlength').requiredLength + ' characters long';
16
- }
17
- if (control.hasError('maxlength')) {
18
- return 'The field must be at max ' + control.getError('maxlength').requiredLength + ' characters long';
19
- }
20
- return;
21
- }
22
- static handleErrors(formGroup, error) {
23
- if (error instanceof HttpErrorResponse) {
24
- const response = error;
25
- switch (response.status) {
26
- case 400:
27
- let unknownFieldName = false;
28
- for (const fieldName in error.error) {
29
- if (error.error.hasOwnProperty(fieldName) && error.error[fieldName] &&
30
- (error.error[fieldName]?.length > 0 || error.error[fieldName]?.Errors?.length > 0)) {
31
- let jsonFieldName = fieldName;
32
- if (jsonFieldName.length > 0) {
33
- jsonFieldName = jsonFieldName[0].toLowerCase() + jsonFieldName.slice(1);
34
- }
35
- const errorMessage = error.error[fieldName]?.Errors?.length > 0 ?
36
- (error.error[fieldName]?.Errors.map((e) => e.ErrorMessage)).join(', ')
37
- : error.error[fieldName];
38
- if (formGroup.controls.hasOwnProperty(jsonFieldName)) {
39
- formGroup.controls[jsonFieldName].setErrors({ serverSide: errorMessage });
40
- }
41
- else {
42
- unknownFieldName = true;
43
- }
44
- }
45
- }
46
- if (unknownFieldName) {
47
- formGroup.setErrors({ serverSide: 'Something went wrong.' });
48
- }
49
- break;
50
- // in these cases we do not show errors on the form, they're handled by the http
51
- // interceptor in src\app\_interceptors\httpstatuscode.interceptor.ts
52
- case 402:
53
- case 429:
54
- return;
55
- }
56
- }
57
- else {
58
- formGroup.setErrors({ serverSide: 'Something went wrong on our side. This is not your fault. Please try again.' });
59
- }
60
- }
61
- /**
62
- * Converts a value representing a number to a `number` value.
63
- * Returns `NaN` in the case of non-numerical values.
64
- */
65
- static normalizeNumber(value) {
66
- switch (typeof value) {
67
- case "number":
68
- return value;
69
- case "string":
70
- // NOTE: `Number()` converts whitespace strings to 0.
71
- return value.trim() === '' ? NaN : Number(value);
72
- case "bigint":
73
- return Number(value);
74
- default:
75
- return NaN;
76
- }
77
- }
78
- /**
79
- * Converts a value representing a number to the normalized `string`
80
- * representation of the number. (e.g. `.1` --> `'0.1'`, `3.14e2` --> `'314'`).
81
- * Returns `''` in the case of non-numerical values or non-finite numerical values.
82
- */
83
- static normalizeNumberStoredAsString(value) {
84
- value = FormHelper.normalizeNumber(value);
85
- // NOTE: `NaN` is not considered finite.
86
- return isFinite(value) ? value + '' : '';
87
- }
88
- static formatNumberForDisplay(value) {
89
- if (!isFinite(value)) {
90
- return '';
91
- }
92
- // Chromium-based browsers don't respect the `lang` attribute,
93
- // they use a display format corresponding to the browser's language setting.
94
- if (PlatformHelper.isChromium()) {
95
- return value.toLocaleString();
96
- }
97
- // Firefox (and probably other browsers) respect the `lang` attribute,
98
- // which is currently set to the fixed value of "en" (see index.html),
99
- // so in these cases dot should be used as the decimal separator.
100
- // (In case localization is implemented in the application, this logic should be revised!)
101
- return value + '';
102
- }
103
- }
104
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1jb25maWdjYXQtcHVibGljYXBpLXVpL3NyYy9saWIvX3NlcnZpY2VzL2Zvcm0taGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXpELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVuRCxNQUFNLE9BQU8sVUFBVTtJQUVaLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBd0IsRUFBRSxPQUFlLEVBQUU7UUFDckUsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFO1lBQzNCLE9BQU87U0FDVjtRQUVELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUM5QixPQUFPLEdBQUcsSUFBSSx5QkFBeUIsQ0FBQztTQUMzQztRQUVELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUM3QixPQUFPLDZCQUE2QixDQUFDO1NBQ3hDO1FBRUQsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQy9CLE9BQU8sNkJBQTZCLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxjQUFjLEdBQUcsa0JBQWtCLENBQUM7U0FDNUc7UUFFRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDL0IsT0FBTywyQkFBMkIsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLGNBQWMsR0FBRyxrQkFBa0IsQ0FBQztTQUMxRztRQUVELE9BQU87SUFDWCxDQUFDO0lBR00sTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFvQixFQUFFLEtBQVU7UUFDdkQsSUFBSSxLQUFLLFlBQVksaUJBQWlCLEVB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QUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFHSSxNQUFNLENBQUMsc0JBQXNCLENBQUMsS0FBYTtRQUNoRCxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3BCLE9BQU8sRUFBRSxDQUFDO1NBQ1g7UUFFRCw4REFBOEQ7UUFDOUQsNkVBQTZFO1FBQzdFLElBQUksY0FBYyxDQUFDLFVBQVUsRUFBRSxFQUFFO1lBQy9CLE9BQU8sS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQy9CO1FBRUQsc0VBQXNFO1FBQ3RFLHNFQUFzRTtRQUN0RSxpRUFBaUU7UUFDakUsMEZBQTBGO1FBQzFGLE9BQU8sS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUNwQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUGxhdGZvcm1IZWxwZXIgfSBmcm9tICcuL3BsYXRmb3JtLWhlbHBlcic7XG5cbmV4cG9ydCBjbGFzcyBGb3JtSGVscGVyIHtcblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0RXJyb3JNZXNzYWdlKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaGludDogc3RyaW5nID0gJycpIHtcbiAgICAgICAgaWYgKCFjb250cm9sIHx8IGNvbnRyb2wudmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250cm9sLmhhc0Vycm9yKCdyZXF1aXJlZCcpKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7aGludH0gVGhlIGZpZWxkIGlzIHJlcXVpcmVkLmA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udHJvbC5oYXNFcnJvcigncGF0dGVybicpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ05vdCBhIHZhbGlkIGUtbWFpbCBhZGRyZXNzLic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udHJvbC5oYXNFcnJvcignbWlubGVuZ3RoJykpIHtcbiAgICAgICAgICAgIHJldHVybiAnVGhlIGZpZWxkIG11c3QgYmUgYXQgbGVhc3QgJyArIGNvbnRyb2wuZ2V0RXJyb3IoJ21pbmxlbmd0aCcpLnJlcXVpcmVkTGVuZ3RoICsgJyBjaGFyYWN0ZXJzIGxvbmcnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRyb2wuaGFzRXJyb3IoJ21heGxlbmd0aCcpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ1RoZSBmaWVsZCBtdXN0IGJlIGF0IG1heCAnICsgY29udHJvbC5nZXRFcnJvcignbWF4bGVuZ3RoJykucmVxdWlyZWRMZW5ndGggKyAnIGNoYXJhY3RlcnMgbG9uZyc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICBwdWJsaWMgc3RhdGljIGhhbmRsZUVycm9ycyhmb3JtR3JvdXA6IEZvcm1Hcm91cCwgZXJyb3I6IGFueSkge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBlcnJvciBhcyBIdHRwRXJyb3JSZXNwb25zZTtcbiAgICAgICAgICAgIHN3aXRjaCAocmVzcG9uc2Uuc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSA0MDA6XG4gICAgICAgICAgICAgICAgICAgIGxldCB1bmtub3duRmllbGROYW1lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIGVycm9yLmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZXJyb3IuaGFzT3duUHJvcGVydHkoZmllbGROYW1lKSAmJiBlcnJvci5lcnJvcltmaWVsZE5hbWVdICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yLmVycm9yW2ZpZWxkTmFtZV0/Lmxlbmd0aCA+IDAgfHwgZXJyb3IuZXJyb3JbZmllbGROYW1lXT8uRXJyb3JzPy5sZW5ndGggPiAwKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBqc29uRmllbGROYW1lID0gZmllbGROYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqc29uRmllbGROYW1lLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbkZpZWxkTmFtZSA9IGpzb25GaWVsZE5hbWVbMF0udG9Mb3dlckNhc2UoKSArIGpzb25GaWVsZE5hbWUuc2xpY2UoMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IuZXJyb3JbZmllbGROYW1lXT8uRXJyb3JzPy5sZW5ndGggPiAwID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yLmVycm9yW2ZpZWxkTmFtZV0/LkVycm9ycy5tYXAoKGU6IGFueSkgPT4gZS5FcnJvck1lc3NhZ2UpKS5qb2luKCcsICcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZXJyb3IuZXJyb3JbZmllbGROYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtR3JvdXAuY29udHJvbHMuaGFzT3duUHJvcGVydHkoanNvbkZpZWxkTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUdyb3VwLmNvbnRyb2xzW2pzb25GaWVsZE5hbWVdLnNldEVycm9ycyh7IHNlcnZlclNpZGU6IGVycm9yTWVzc2FnZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duRmllbGROYW1lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHVua25vd25GaWVsZE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Hcm91cC5zZXRFcnJvcnMoeyBzZXJ2ZXJTaWRlOiAnU29tZXRoaW5nIHdlbnQgd3JvbmcuJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAvLyBpbiB0aGVzZSBjYXNlcyB3ZSBkbyBub3Qgc2hvdyBlcnJvcnMgb24gdGhlIGZvcm0sIHRoZXkncmUgaGFuZGxlZCBieSB0aGUgaHR0cFxuICAgICAgICAgICAgICAgIC8vIGludGVyY2VwdG9yIGluIHNyY1xcYXBwXFxfaW50ZXJjZXB0b3JzXFxodHRwc3RhdHVzY29kZS5pbnRlcmNlcHRvci50c1xuICAgICAgICAgICAgICAgIGNhc2UgNDAyOlxuICAgICAgICAgICAgICAgIGNhc2UgNDI5OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JtR3JvdXAuc2V0RXJyb3JzKHsgc2VydmVyU2lkZTogJ1NvbWV0aGluZyB3ZW50IHdyb25nIG9uIG91ciBzaWRlLiBUaGlzIGlzIG5vdCB5b3VyIGZhdWx0LiBQbGVhc2UgdHJ5IGFnYWluLicgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhIHZhbHVlIHJlcHJlc2VudGluZyBhIG51bWJlciB0byBhIGBudW1iZXJgIHZhbHVlLlxuICAgICAqIFJldHVybnMgYE5hTmAgaW4gdGhlIGNhc2Ugb2Ygbm9uLW51bWVyaWNhbCB2YWx1ZXMuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBub3JtYWxpemVOdW1iZXIodmFsdWU6IGFueSk6IG51bWJlciB7XG4gICAgICAgIHN3aXRjaCAodHlwZW9mIHZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgICAgIC8vIE5PVEU6IGBOdW1iZXIoKWAgY29udmVydHMgd2hpdGVzcGFjZSBzdHJpbmdzIHRvIDAuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRyaW0oKSA9PT0gJycgPyBOYU4gOiBOdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSB2YWx1ZSByZXByZXNlbnRpbmcgYSBudW1iZXIgdG8gdGhlIG5vcm1hbGl6ZWQgYHN0cmluZ2BcbiAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgbnVtYmVyLiAoZS5nLiBgLjFgIC0tPiBgJzAuMSdgLCBgMy4xNGUyYCAtLT4gYCczMTQnYCkuXG4gICAgICogUmV0dXJucyBgJydgIGluIHRoZSBjYXNlIG9mIG5vbi1udW1lcmljYWwgdmFsdWVzIG9yIG5vbi1maW5pdGUgbnVtZXJpY2FsIHZhbHVlcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIG5vcm1hbGl6ZU51bWJlclN0b3JlZEFzU3RyaW5nKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgICAgICB2YWx1ZSA9IEZvcm1IZWxwZXIubm9ybWFsaXplTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgLy8gTk9URTogYE5hTmAgaXMgbm90IGNvbnNpZGVyZWQgZmluaXRlLlxuICAgICAgICByZXR1cm4gaXNGaW5pdGUodmFsdWUpID8gdmFsdWUgKyAnJyA6ICcnO1xuICAgIH1cblxuICAgIFxuICBwdWJsaWMgc3RhdGljIGZvcm1hdE51bWJlckZvckRpc3BsYXkodmFsdWU6IG51bWJlcikge1xuICAgIGlmICghaXNGaW5pdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gQ2hyb21pdW0tYmFzZWQgYnJvd3NlcnMgZG9uJ3QgcmVzcGVjdCB0aGUgYGxhbmdgIGF0dHJpYnV0ZSxcbiAgICAvLyB0aGV5IHVzZSBhIGRpc3BsYXkgZm9ybWF0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGJyb3dzZXIncyBsYW5ndWFnZSBzZXR0aW5nLlxuICAgIGlmIChQbGF0Zm9ybUhlbHBlci5pc0Nocm9taXVtKCkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b0xvY2FsZVN0cmluZygpO1xuICAgIH1cblxuICAgIC8vIEZpcmVmb3ggKGFuZCBwcm9iYWJseSBvdGhlciBicm93c2VycykgcmVzcGVjdCB0aGUgYGxhbmdgIGF0dHJpYnV0ZSxcbiAgICAvLyB3aGljaCBpcyBjdXJyZW50bHkgc2V0IHRvIHRoZSBmaXhlZCB2YWx1ZSBvZiBcImVuXCIgKHNlZSBpbmRleC5odG1sKSxcbiAgICAvLyBzbyBpbiB0aGVzZSBjYXNlcyBkb3Qgc2hvdWxkIGJlIHVzZWQgYXMgdGhlIGRlY2ltYWwgc2VwYXJhdG9yLlxuICAgIC8vIChJbiBjYXNlIGxvY2FsaXphdGlvbiBpcyBpbXBsZW1lbnRlZCBpbiB0aGUgYXBwbGljYXRpb24sIHRoaXMgbG9naWMgc2hvdWxkIGJlIHJldmlzZWQhKVxuICAgIHJldHVybiB2YWx1ZSArICcnO1xuICB9XG59XG4iXX0=