@qbs-origin/origin-form 0.5.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.
- package/README.md +24 -0
- package/esm2022/lib/action-step-handler.mjs +163 -0
- package/esm2022/lib/auth-client.service.mjs +69 -0
- package/esm2022/lib/enums/label.keys.mjs +721 -0
- package/esm2022/lib/form-css.helper.mjs +367 -0
- package/esm2022/lib/formly/baseFormlyControlComponent.mjs +52 -0
- package/esm2022/lib/formly/baseFormlyStepComponent.mjs +59 -0
- package/esm2022/lib/formly/custom-section-separator.component.mjs +32 -0
- package/esm2022/lib/formly/form-section-separator.component.mjs +36 -0
- package/esm2022/lib/formly/formly-action.mjs +56 -0
- package/esm2022/lib/formly/formly-checkbox/formly-checkbox.component.mjs +52 -0
- package/esm2022/lib/formly/formly-dictionary-dropdown-tree/formly-dictionary-dropdown-tree.component.mjs +261 -0
- package/esm2022/lib/formly/formly-download-documents/formly-download-documents.component.mjs +126 -0
- package/esm2022/lib/formly/formly-enrol-card/formly-enrol-card.component.mjs +120 -0
- package/esm2022/lib/formly/formly-field-stepper/formly-field-stepper.component.mjs +762 -0
- package/esm2022/lib/formly/formly-generate-documents/formly-generate-documents.component.mjs +57 -0
- package/esm2022/lib/formly/formly-identification.component.mjs +84 -0
- package/esm2022/lib/formly/formly-open-banking/formly-open-banking.component.mjs +590 -0
- package/esm2022/lib/formly/formly-paragraph/formly-paragraph.component.mjs +35 -0
- package/esm2022/lib/formly/formly-radio/formly-radio-component.mjs +49 -0
- package/esm2022/lib/formly/formly-row-fille.mjs +12 -0
- package/esm2022/lib/formly/formly-scan-id/formly-scan-id.component.mjs +284 -0
- package/esm2022/lib/formly/formly-sign/formly-sign.component.mjs +173 -0
- package/esm2022/lib/formly/formly-upload-documents/formly-upload-documents.component.mjs +198 -0
- package/esm2022/lib/formly/formly-validate-contact-info/formly-validate-contact-info.component.mjs +124 -0
- package/esm2022/lib/formly/formly-view-documents/formly-view-documents.component.mjs +245 -0
- package/esm2022/lib/formly/formly-view-offers/formly-view-offers.component.mjs +160 -0
- package/esm2022/lib/model-population.helper.mjs +265 -0
- package/esm2022/lib/models/application-type.model.mjs +12 -0
- package/esm2022/lib/models/application.model.mjs +30 -0
- package/esm2022/lib/models/auth/users.model.mjs +2 -0
- package/esm2022/lib/models/dictionary.model.mjs +20 -0
- package/esm2022/lib/models/flux.model.mjs +105 -0
- package/esm2022/lib/models/forms.model.mjs +572 -0
- package/esm2022/lib/models/label-info.model.mjs +2 -0
- package/esm2022/lib/models/label.model.mjs +2 -0
- package/esm2022/lib/models/language.model.mjs +3 -0
- package/esm2022/lib/models/list.model.mjs +2 -0
- package/esm2022/lib/models/partner.model.mjs +3 -0
- package/esm2022/lib/models/treeview.model.mjs +15 -0
- package/esm2022/lib/origin-form-auth.service.mjs +40 -0
- package/esm2022/lib/origin-form-config.model.mjs +2 -0
- package/esm2022/lib/origin-form-token.interceptor.mjs +35 -0
- package/esm2022/lib/origin-form.component.mjs +2391 -0
- package/esm2022/lib/origin-form.module.mjs +479 -0
- package/esm2022/lib/origin-form.service.mjs +14 -0
- package/esm2022/lib/others/check-list.database.mjs +55 -0
- package/esm2022/lib/others/config-service.mjs +42 -0
- package/esm2022/lib/others/dictionary-label-info.mjs +3 -0
- package/esm2022/lib/others/environment-type.mjs +21 -0
- package/esm2022/lib/others/external-link.directive.mjs +49 -0
- package/esm2022/lib/others/flux-helper.mjs +1397 -0
- package/esm2022/lib/others/picker.component.mjs +119 -0
- package/esm2022/lib/others/translation.pipe.mjs +21 -0
- package/esm2022/lib/others/translations-helper.mjs +258 -0
- package/esm2022/lib/others/utils.mjs +272 -0
- package/esm2022/lib/services/applicationData.service.mjs +145 -0
- package/esm2022/lib/services/auth-http.service.mjs +80 -0
- package/esm2022/lib/services/dialog.service.mjs +56 -0
- package/esm2022/lib/services/dictionary.service.mjs +198 -0
- package/esm2022/lib/services/forms.service.mjs +47 -0
- package/esm2022/lib/services/labels.service.mjs +29 -0
- package/esm2022/lib/services/language.service.mjs +24 -0
- package/esm2022/lib/services/open-banking.service.mjs +194 -0
- package/esm2022/lib/services/origin-form-signalr-handler.service.mjs +107 -0
- package/esm2022/lib/services/origin-form-signalr.service.mjs +105 -0
- package/esm2022/lib/services/otp.service.mjs +28 -0
- package/esm2022/lib/services/proxy.service.mjs +79 -0
- package/esm2022/lib/services/scroll-to-error.service.mjs +369 -0
- package/esm2022/lib/services/translation.service.mjs +27 -0
- package/esm2022/lib/shared-components/confirmation.component.mjs +34 -0
- package/esm2022/lib/shared-components/dictionaries-tree.component.mjs +301 -0
- package/esm2022/lib/shared-components/grid.component.mjs +241 -0
- package/esm2022/lib/shared-components/treeview/treeview.component.mjs +224 -0
- package/esm2022/lib/theme-css.mjs +2254 -0
- package/esm2022/lib/theme-injector.service.mjs +26 -0
- package/esm2022/public-api.mjs +4 -0
- package/esm2022/qbs-origin-origin-form.mjs +5 -0
- package/fesm2022/qbs-origin-origin-form.mjs +15215 -0
- package/fesm2022/qbs-origin-origin-form.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/action-step-handler.d.ts +49 -0
- package/lib/auth-client.service.d.ts +17 -0
- package/lib/enums/label.keys.d.ts +720 -0
- package/lib/form-css.helper.d.ts +28 -0
- package/lib/formly/baseFormlyControlComponent.d.ts +25 -0
- package/lib/formly/baseFormlyStepComponent.d.ts +29 -0
- package/lib/formly/custom-section-separator.component.d.ts +6 -0
- package/lib/formly/form-section-separator.component.d.ts +10 -0
- package/lib/formly/formly-action.d.ts +13 -0
- package/lib/formly/formly-checkbox/formly-checkbox.component.d.ts +15 -0
- package/lib/formly/formly-dictionary-dropdown-tree/formly-dictionary-dropdown-tree.component.d.ts +45 -0
- package/lib/formly/formly-download-documents/formly-download-documents.component.d.ts +22 -0
- package/lib/formly/formly-enrol-card/formly-enrol-card.component.d.ts +114 -0
- package/lib/formly/formly-field-stepper/formly-field-stepper.component.d.ts +79 -0
- package/lib/formly/formly-generate-documents/formly-generate-documents.component.d.ts +17 -0
- package/lib/formly/formly-identification.component.d.ts +19 -0
- package/lib/formly/formly-open-banking/formly-open-banking.component.d.ts +119 -0
- package/lib/formly/formly-paragraph/formly-paragraph.component.d.ts +10 -0
- package/lib/formly/formly-radio/formly-radio-component.d.ts +15 -0
- package/lib/formly/formly-row-fille.d.ts +6 -0
- package/lib/formly/formly-scan-id/formly-scan-id.component.d.ts +41 -0
- package/lib/formly/formly-sign/formly-sign.component.d.ts +36 -0
- package/lib/formly/formly-upload-documents/formly-upload-documents.component.d.ts +25 -0
- package/lib/formly/formly-validate-contact-info/formly-validate-contact-info.component.d.ts +79 -0
- package/lib/formly/formly-view-documents/formly-view-documents.component.d.ts +33 -0
- package/lib/formly/formly-view-offers/formly-view-offers.component.d.ts +23 -0
- package/lib/model-population.helper.d.ts +8 -0
- package/lib/models/application-type.model.d.ts +27 -0
- package/lib/models/application.model.d.ts +107 -0
- package/lib/models/auth/users.model.d.ts +20 -0
- package/lib/models/dictionary.model.d.ts +77 -0
- package/lib/models/flux.model.d.ts +101 -0
- package/lib/models/forms.model.d.ts +504 -0
- package/lib/models/label-info.model.d.ts +10 -0
- package/lib/models/label.model.d.ts +4 -0
- package/lib/models/language.model.d.ts +5 -0
- package/lib/models/list.model.d.ts +8 -0
- package/lib/models/partner.model.d.ts +12 -0
- package/lib/models/treeview.model.d.ts +17 -0
- package/lib/origin-form-auth.service.d.ts +15 -0
- package/lib/origin-form-config.model.d.ts +12 -0
- package/lib/origin-form-token.interceptor.d.ts +12 -0
- package/lib/origin-form.component.d.ts +231 -0
- package/lib/origin-form.module.d.ts +84 -0
- package/lib/origin-form.service.d.ts +6 -0
- package/lib/others/check-list.database.d.ts +16 -0
- package/lib/others/config-service.d.ts +22 -0
- package/lib/others/dictionary-label-info.d.ts +6 -0
- package/lib/others/environment-type.d.ts +8 -0
- package/lib/others/external-link.directive.d.ts +12 -0
- package/lib/others/flux-helper.d.ts +115 -0
- package/lib/others/picker.component.d.ts +36 -0
- package/lib/others/translation.pipe.d.ts +10 -0
- package/lib/others/translations-helper.d.ts +31 -0
- package/lib/others/utils.d.ts +37 -0
- package/lib/services/applicationData.service.d.ts +35 -0
- package/lib/services/auth-http.service.d.ts +21 -0
- package/lib/services/dialog.service.d.ts +20 -0
- package/lib/services/dictionary.service.d.ts +89 -0
- package/lib/services/forms.service.d.ts +17 -0
- package/lib/services/labels.service.d.ts +13 -0
- package/lib/services/language.service.d.ts +14 -0
- package/lib/services/open-banking.service.d.ts +137 -0
- package/lib/services/origin-form-signalr-handler.service.d.ts +29 -0
- package/lib/services/origin-form-signalr.service.d.ts +24 -0
- package/lib/services/otp.service.d.ts +22 -0
- package/lib/services/proxy.service.d.ts +29 -0
- package/lib/services/scroll-to-error.service.d.ts +54 -0
- package/lib/services/translation.service.d.ts +10 -0
- package/lib/shared-components/confirmation.component.d.ts +77 -0
- package/lib/shared-components/dictionaries-tree.component.d.ts +51 -0
- package/lib/shared-components/grid.component.d.ts +138 -0
- package/lib/shared-components/treeview/treeview.component.d.ts +121 -0
- package/lib/theme-css.d.ts +2 -0
- package/lib/theme-injector.service.d.ts +8 -0
- package/package.json +42 -0
- package/public-api.d.ts +3 -0
- package/schematics-compiled/collection.json +10 -0
- package/schematics-compiled/ng-add/index.d.ts +2 -0
- package/schematics-compiled/ng-add/index.js +67 -0
- package/schematics-compiled/ng-add/index.js.map +1 -0
- package/schematics-compiled/ng-add/schema.json +8 -0
- package/src/lib/assets/fonts/Figtree-Bold.ttf +0 -0
- package/src/lib/assets/fonts/Figtree-Light.ttf +0 -0
- package/src/lib/assets/fonts/Figtree-Regular.ttf +0 -0
- package/src/lib/assets/fonts/Sora-ExtraBold.ttf +0 -0
- package/src/lib/assets/fonts/Sora-Light.ttf +0 -0
- package/src/lib/assets/fonts/Sora-Regular.ttf +0 -0
- package/src/lib/assets/fonts/ttrounds-bold-webfont.woff +0 -0
- package/src/lib/assets/fonts/ttrounds-bold-webfont.woff2 +0 -0
- package/src/lib/assets/fonts/ttrounds-regular-webfont.woff +0 -0
- package/src/lib/assets/fonts/ttrounds-regular-webfont.woff2 +0 -0
- package/src/lib/assets/fonts/ttrounds-thin-webfont.woff +0 -0
- package/src/lib/assets/fonts/ttrounds-thin-webfont.woff2 +0 -0
- package/src/lib/assets/images/flag/icon-flag-de.svg +10 -0
- package/src/lib/assets/images/flag/icon-flag-en.svg +1 -0
- package/src/lib/assets/images/flag/icon-flag-es.svg +11 -0
- package/src/lib/assets/images/flag/icon-flag-fr.svg +1 -0
- package/src/lib/assets/images/flag/icon-flag-ro.svg +11 -0
- package/src/lib/assets/images/flag/origin-form/new-id-card.png +0 -0
- package/src/lib/assets/images/flag/origin-form/old-id-card.png +0 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { FormGroup } from '@angular/forms';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class ScrollToErrorService {
|
|
5
|
+
/**
|
|
6
|
+
* Scroll to the first validation error in a form
|
|
7
|
+
*/
|
|
8
|
+
scrollToFirstError(form) {
|
|
9
|
+
try {
|
|
10
|
+
// Find the first invalid control
|
|
11
|
+
const firstInvalidControl = this.findFirstInvalidControl(form);
|
|
12
|
+
if (firstInvalidControl) {
|
|
13
|
+
this.scrollToField(firstInvalidControl.name);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error('Error scrolling to first error:', error);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Scroll to a specific field by name
|
|
22
|
+
*/
|
|
23
|
+
scrollToField(fieldName) {
|
|
24
|
+
// Add a small delay to ensure DOM is ready
|
|
25
|
+
setTimeout(() => {
|
|
26
|
+
const element = this.findFormFieldElement(fieldName);
|
|
27
|
+
if (element) {
|
|
28
|
+
this.scrollToElement(element);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
this.tryFindMatchingInvalidField(fieldName);
|
|
32
|
+
}
|
|
33
|
+
}, 100);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Find first invalid control in form
|
|
37
|
+
*/
|
|
38
|
+
findFirstInvalidControl(formGroup, parentName = '') {
|
|
39
|
+
for (const controlName in formGroup.controls) {
|
|
40
|
+
const control = formGroup.controls[controlName];
|
|
41
|
+
const fullControlName = parentName ? `${parentName}.${controlName}` : controlName;
|
|
42
|
+
if (control instanceof FormGroup) {
|
|
43
|
+
const nestedInvalid = this.findFirstInvalidControl(control, fullControlName);
|
|
44
|
+
if (nestedInvalid) {
|
|
45
|
+
return nestedInvalid;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Check if this control is invalid
|
|
50
|
+
if (control.invalid && (control.dirty || control.touched)) {
|
|
51
|
+
return { name: fullControlName, control };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Find form field element by various selectors
|
|
59
|
+
*/
|
|
60
|
+
findFormFieldElement(fieldName) {
|
|
61
|
+
if (!fieldName)
|
|
62
|
+
return null;
|
|
63
|
+
// Clean the field name for better matching
|
|
64
|
+
const cleanFieldName = fieldName.replace(/[.\[\]]/g, '');
|
|
65
|
+
// Try various selectors to find the form field
|
|
66
|
+
const selectors = [
|
|
67
|
+
// Formly specific selectors
|
|
68
|
+
`formly-field[ng-reflect-field*="${fieldName}"]`,
|
|
69
|
+
`formly-field[ng-reflect-field*="${cleanFieldName}"]`,
|
|
70
|
+
`[data-cy="${fieldName}"]`,
|
|
71
|
+
`[data-cy="${cleanFieldName}"]`,
|
|
72
|
+
// Form control selectors
|
|
73
|
+
`input[formcontrolname="${fieldName}"]`,
|
|
74
|
+
`select[formcontrolname="${fieldName}"]`,
|
|
75
|
+
`textarea[formcontrolname="${fieldName}"]`,
|
|
76
|
+
`input[formcontrolname="${cleanFieldName}"]`,
|
|
77
|
+
`select[formcontrolname="${cleanFieldName}"]`,
|
|
78
|
+
`textarea[formcontrolname="${cleanFieldName}"]`,
|
|
79
|
+
// Name and ID selectors
|
|
80
|
+
`input[name="${fieldName}"]`,
|
|
81
|
+
`select[name="${fieldName}"]`,
|
|
82
|
+
`textarea[name="${fieldName}"]`,
|
|
83
|
+
`#${fieldName}`,
|
|
84
|
+
`#${cleanFieldName}`,
|
|
85
|
+
// Class selectors
|
|
86
|
+
`.field-${fieldName}`,
|
|
87
|
+
`.field-${cleanFieldName}`,
|
|
88
|
+
// Angular Material specific
|
|
89
|
+
`mat-form-field:has(input[formcontrolname="${fieldName}"])`,
|
|
90
|
+
`mat-form-field:has(select[formcontrolname="${fieldName}"])`,
|
|
91
|
+
`mat-form-field:has(textarea[formcontrolname="${fieldName}"])`,
|
|
92
|
+
// Generic error class selectors
|
|
93
|
+
`.ng-invalid[formcontrolname="${fieldName}"]`,
|
|
94
|
+
`.ng-invalid[name="${fieldName}"]`,
|
|
95
|
+
// Broader searches
|
|
96
|
+
`[ng-reflect-name="${fieldName}"]`,
|
|
97
|
+
`[ng-reflect-key="${fieldName}"]`
|
|
98
|
+
];
|
|
99
|
+
for (const selector of selectors) {
|
|
100
|
+
try {
|
|
101
|
+
const element = document.querySelector(selector);
|
|
102
|
+
if (element && this.isElementVisible(element)) {
|
|
103
|
+
return element;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// Some selectors might be invalid, continue trying others
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Fallback: search through all elements
|
|
112
|
+
return this.fallbackElementSearch(fieldName, cleanFieldName);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Fallback search through all elements
|
|
116
|
+
*/
|
|
117
|
+
fallbackElementSearch(fieldName, cleanFieldName) {
|
|
118
|
+
const allElements = document.querySelectorAll('input, select, textarea, formly-field, mat-form-field');
|
|
119
|
+
for (const element of Array.from(allElements)) {
|
|
120
|
+
const htmlElement = element;
|
|
121
|
+
// Check various attributes
|
|
122
|
+
const attributes = [
|
|
123
|
+
'formcontrolname',
|
|
124
|
+
'name',
|
|
125
|
+
'id',
|
|
126
|
+
'ng-reflect-name',
|
|
127
|
+
'ng-reflect-key',
|
|
128
|
+
'data-cy'
|
|
129
|
+
];
|
|
130
|
+
for (const attr of attributes) {
|
|
131
|
+
const attrValue = htmlElement.getAttribute(attr);
|
|
132
|
+
if (attrValue === fieldName || attrValue === cleanFieldName) {
|
|
133
|
+
if (this.isElementVisible(htmlElement)) {
|
|
134
|
+
return htmlElement;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Check class names
|
|
139
|
+
if (htmlElement.classList.contains(`field-${fieldName}`) ||
|
|
140
|
+
htmlElement.classList.contains(`field-${cleanFieldName}`)) {
|
|
141
|
+
if (this.isElementVisible(htmlElement)) {
|
|
142
|
+
return htmlElement;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if element is visible
|
|
150
|
+
*/
|
|
151
|
+
isElementVisible(element) {
|
|
152
|
+
const rect = element.getBoundingClientRect();
|
|
153
|
+
const style = window.getComputedStyle(element);
|
|
154
|
+
return rect.width > 0 &&
|
|
155
|
+
rect.height > 0 &&
|
|
156
|
+
style.visibility !== 'hidden' &&
|
|
157
|
+
style.display !== 'none' &&
|
|
158
|
+
style.opacity !== '0';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Try to find a matching invalid field when direct search fails
|
|
162
|
+
*/
|
|
163
|
+
tryFindMatchingInvalidField(fieldName) {
|
|
164
|
+
const cleanFieldName = fieldName.replace(/[.\[\]]/g, '');
|
|
165
|
+
// Get all invalid elements
|
|
166
|
+
const invalidElements = document.querySelectorAll('.ng-invalid');
|
|
167
|
+
// Try to find one that matches our field name
|
|
168
|
+
for (const element of Array.from(invalidElements)) {
|
|
169
|
+
const htmlElement = element;
|
|
170
|
+
// Check if this invalid element matches our field
|
|
171
|
+
const attributes = ['formcontrolname', 'name', 'id', 'ng-reflect-name', 'ng-reflect-key'];
|
|
172
|
+
for (const attr of attributes) {
|
|
173
|
+
const attrValue = htmlElement.getAttribute(attr);
|
|
174
|
+
if (attrValue === fieldName || attrValue === cleanFieldName) {
|
|
175
|
+
if (this.isElementVisible(htmlElement)) {
|
|
176
|
+
this.scrollToElement(htmlElement);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Check for partial matches in IDs (formly generates IDs with field names)
|
|
182
|
+
const id = htmlElement.getAttribute('id');
|
|
183
|
+
if (id && (id.includes(fieldName) || id.includes(cleanFieldName))) {
|
|
184
|
+
if (this.isElementVisible(htmlElement)) {
|
|
185
|
+
this.scrollToElement(htmlElement);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// If no matching invalid element found, try formly field containers
|
|
191
|
+
this.tryFindFormlyFieldContainer(fieldName, cleanFieldName);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Try to find formly field container and look for invalid elements within it
|
|
195
|
+
*/
|
|
196
|
+
tryFindFormlyFieldContainer(fieldName, cleanFieldName) {
|
|
197
|
+
const formlyFields = document.querySelectorAll('formly-field');
|
|
198
|
+
for (const formlyField of Array.from(formlyFields)) {
|
|
199
|
+
const fieldElement = formlyField;
|
|
200
|
+
// Check if this formly field's ng-reflect-field contains our field name
|
|
201
|
+
const ngReflectField = fieldElement.getAttribute('ng-reflect-field');
|
|
202
|
+
if (ngReflectField &&
|
|
203
|
+
(ngReflectField.includes(`"key":"${fieldName}"`) ||
|
|
204
|
+
ngReflectField.includes(`"key":"${cleanFieldName}"`))) {
|
|
205
|
+
// Look for invalid elements within this container
|
|
206
|
+
const invalidInContainer = fieldElement.querySelector('.ng-invalid');
|
|
207
|
+
if (invalidInContainer && this.isElementVisible(invalidInContainer)) {
|
|
208
|
+
this.scrollToElement(invalidInContainer);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
// If no invalid element, scroll to the container itself
|
|
212
|
+
if (this.isElementVisible(fieldElement)) {
|
|
213
|
+
this.scrollToElement(fieldElement);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Last resort: scroll to first visible invalid element
|
|
219
|
+
const invalidElements = document.querySelectorAll('.ng-invalid');
|
|
220
|
+
for (const element of Array.from(invalidElements)) {
|
|
221
|
+
const htmlElement = element;
|
|
222
|
+
if (this.isElementVisible(htmlElement)) {
|
|
223
|
+
this.scrollToElement(htmlElement);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
console.warn(`❌ Could not find any suitable element to scroll to for field: ${fieldName}`);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Scroll to element with smooth animation
|
|
231
|
+
*/
|
|
232
|
+
scrollToElement(element) {
|
|
233
|
+
try {
|
|
234
|
+
// Find the closest form field container
|
|
235
|
+
const formFieldContainer = element.closest('mat-form-field, formly-field, .form-field, .mat-mdc-form-field, .form-group');
|
|
236
|
+
const targetElement = formFieldContainer || element;
|
|
237
|
+
// Calculate offset to show element with some margin from top
|
|
238
|
+
const offset = 100; // pixels from top (increased for better visibility)
|
|
239
|
+
const elementPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
|
|
240
|
+
const offsetPosition = Math.max(0, elementPosition - offset);
|
|
241
|
+
// Use multiple scroll methods for better compatibility
|
|
242
|
+
this.performScroll(offsetPosition, element); // Pass the original element for focusing
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
console.error('Error scrolling to element:', error);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Perform the actual scroll with multiple methods
|
|
250
|
+
*/
|
|
251
|
+
performScroll(targetPosition, elementToFocus) {
|
|
252
|
+
// Method 1: Modern smooth scroll
|
|
253
|
+
try {
|
|
254
|
+
window.scrollTo({
|
|
255
|
+
top: targetPosition,
|
|
256
|
+
behavior: 'smooth'
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
// Fallback for older browsers
|
|
261
|
+
window.scrollTo(0, targetPosition);
|
|
262
|
+
}
|
|
263
|
+
// Method 2: ScrollIntoView as backup
|
|
264
|
+
setTimeout(() => {
|
|
265
|
+
try {
|
|
266
|
+
elementToFocus.scrollIntoView({
|
|
267
|
+
behavior: 'smooth',
|
|
268
|
+
block: 'center',
|
|
269
|
+
inline: 'nearest'
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
// Fallback for older browsers
|
|
274
|
+
elementToFocus.scrollIntoView();
|
|
275
|
+
}
|
|
276
|
+
}, 100);
|
|
277
|
+
// Method 3: Focus with delay to ensure scroll completion
|
|
278
|
+
setTimeout(() => {
|
|
279
|
+
this.focusElement(elementToFocus);
|
|
280
|
+
}, 600); // Wait for scroll animation to complete
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Focus on the target element
|
|
284
|
+
*/
|
|
285
|
+
focusElement(targetElement) {
|
|
286
|
+
try {
|
|
287
|
+
// If the target element is directly focusable and invalid, focus it
|
|
288
|
+
if (targetElement.classList.contains('ng-invalid') &&
|
|
289
|
+
(targetElement instanceof HTMLInputElement ||
|
|
290
|
+
targetElement instanceof HTMLSelectElement ||
|
|
291
|
+
targetElement instanceof HTMLTextAreaElement)) {
|
|
292
|
+
targetElement.focus();
|
|
293
|
+
// For input elements, also select the text
|
|
294
|
+
if (targetElement instanceof HTMLInputElement && targetElement.type === 'text') {
|
|
295
|
+
targetElement.select();
|
|
296
|
+
}
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
// Look for invalid focusable elements within the target
|
|
300
|
+
const invalidFocusableSelectors = [
|
|
301
|
+
'input.ng-invalid:not([disabled]):not([readonly])',
|
|
302
|
+
'select.ng-invalid:not([disabled])',
|
|
303
|
+
'textarea.ng-invalid:not([disabled]):not([readonly])',
|
|
304
|
+
'mat-radio-group.ng-invalid',
|
|
305
|
+
'mat-checkbox.ng-invalid'
|
|
306
|
+
];
|
|
307
|
+
for (const selector of invalidFocusableSelectors) {
|
|
308
|
+
const focusableElement = targetElement.querySelector(selector);
|
|
309
|
+
if (focusableElement && this.isElementVisible(focusableElement)) {
|
|
310
|
+
focusableElement.focus();
|
|
311
|
+
// For input elements, also select the text
|
|
312
|
+
if (focusableElement instanceof HTMLInputElement && focusableElement.type === 'text') {
|
|
313
|
+
focusableElement.select();
|
|
314
|
+
}
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
// If no invalid elements found, look for any focusable elements
|
|
319
|
+
const focusableSelectors = [
|
|
320
|
+
'input:not([disabled]):not([readonly])',
|
|
321
|
+
'select:not([disabled])',
|
|
322
|
+
'textarea:not([disabled]):not([readonly])',
|
|
323
|
+
'button:not([disabled])',
|
|
324
|
+
'mat-radio-group',
|
|
325
|
+
'mat-checkbox',
|
|
326
|
+
'[tabindex="0"]'
|
|
327
|
+
];
|
|
328
|
+
for (const selector of focusableSelectors) {
|
|
329
|
+
const focusableElement = targetElement.querySelector(selector);
|
|
330
|
+
if (focusableElement && this.isElementVisible(focusableElement)) {
|
|
331
|
+
focusableElement.focus();
|
|
332
|
+
// For input elements, also select the text
|
|
333
|
+
if (focusableElement instanceof HTMLInputElement && focusableElement.type === 'text') {
|
|
334
|
+
focusableElement.select();
|
|
335
|
+
}
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
// If no focusable element found, try to focus the target itself
|
|
340
|
+
if (targetElement.tabIndex >= 0) {
|
|
341
|
+
targetElement.focus();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
console.error('Error focusing element:', error);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Debug log all form elements for troubleshooting
|
|
350
|
+
*/
|
|
351
|
+
debugLogFormElements() {
|
|
352
|
+
console.group('🐛 Form Elements Debug');
|
|
353
|
+
const formElements = document.querySelectorAll('input, select, textarea, formly-field');
|
|
354
|
+
formElements.forEach((element, index) => {
|
|
355
|
+
const htmlElement = element;
|
|
356
|
+
});
|
|
357
|
+
const invalidElements = document.querySelectorAll('.ng-invalid');
|
|
358
|
+
console.groupEnd();
|
|
359
|
+
}
|
|
360
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollToErrorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
361
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollToErrorService, providedIn: 'root' }); }
|
|
362
|
+
}
|
|
363
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollToErrorService, decorators: [{
|
|
364
|
+
type: Injectable,
|
|
365
|
+
args: [{
|
|
366
|
+
providedIn: 'root'
|
|
367
|
+
}]
|
|
368
|
+
}] });
|
|
369
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsLXRvLWVycm9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vcmlnaW4tZm9ybS9zcmMvbGliL3NlcnZpY2VzL3Njcm9sbC10by1lcnJvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFtQixTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFLNUQsTUFBTSxPQUFPLG9CQUFvQjtJQUUvQjs7T0FFRztJQUNILGtCQUFrQixDQUFDLElBQWU7UUFDaEMsSUFBSSxDQUFDO1lBQ0gsaUNBQWlDO1lBQ2pDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9ELElBQUksbUJBQW1CLEVBQUUsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQyxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzFELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxhQUFhLENBQUMsU0FBaUI7UUFDN0IsMkNBQTJDO1FBQzNDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDckQsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDWixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2hDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsMkJBQTJCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUMsRUFBRSxH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QUMsS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFFeEMsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDLHVDQUF1QyxDQUFDLENBQUM7UUFFeEYsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUN0QyxNQUFNLFdBQVcsR0FBRyxPQUFzQixDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRWpFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNyQixDQUFDOytHQXRaVSxvQkFBb0I7bUhBQXBCLG9CQUFvQixjQUZuQixNQUFNOzs0RkFFUCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFNjcm9sbFRvRXJyb3JTZXJ2aWNlIHtcblxuICAvKipcbiAgICogU2Nyb2xsIHRvIHRoZSBmaXJzdCB2YWxpZGF0aW9uIGVycm9yIGluIGEgZm9ybVxuICAgKi9cbiAgc2Nyb2xsVG9GaXJzdEVycm9yKGZvcm06IEZvcm1Hcm91cCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICAvLyBGaW5kIHRoZSBmaXJzdCBpbnZhbGlkIGNvbnRyb2xcbiAgICAgIGNvbnN0IGZpcnN0SW52YWxpZENvbnRyb2wgPSB0aGlzLmZpbmRGaXJzdEludmFsaWRDb250cm9sKGZvcm0pO1xuICAgICAgaWYgKGZpcnN0SW52YWxpZENvbnRyb2wpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxUb0ZpZWxkKGZpcnN0SW52YWxpZENvbnRyb2wubmFtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNjcm9sbGluZyB0byBmaXJzdCBlcnJvcjonLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNjcm9sbCB0byBhIHNwZWNpZmljIGZpZWxkIGJ5IG5hbWVcbiAgICovXG4gIHNjcm9sbFRvRmllbGQoZmllbGROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyBBZGQgYSBzbWFsbCBkZWxheSB0byBlbnN1cmUgRE9NIGlzIHJlYWR5XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5maW5kRm9ybUZpZWxkRWxlbWVudChmaWVsZE5hbWUpO1xuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxUb0VsZW1lbnQoZWxlbWVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRyeUZpbmRNYXRjaGluZ0ludmFsaWRGaWVsZChmaWVsZE5hbWUpO1xuICAgICAgfVxuICAgIH0sIDEwMCk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBmaXJzdCBpbnZhbGlkIGNvbnRyb2wgaW4gZm9ybVxuICAgKi9cbiAgcHJpdmF0ZSBmaW5kRmlyc3RJbnZhbGlkQ29udHJvbChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgcGFyZW50TmFtZSA9ICcnKTogeyBuYW1lOiBzdHJpbmc7IGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB9IHwgbnVsbCB7XG4gICAgZm9yIChjb25zdCBjb250cm9sTmFtZSBpbiBmb3JtR3JvdXAuY29udHJvbHMpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtR3JvdXAuY29udHJvbHNbY29udHJvbE5hbWVdO1xuICAgICAgY29uc3QgZnVsbENvbnRyb2xOYW1lID0gcGFyZW50TmFtZSA/IGAke3BhcmVudE5hbWV9LiR7Y29udHJvbE5hbWV9YCA6IGNvbnRyb2xOYW1lO1xuXG4gICAgICBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICBjb25zdCBuZXN0ZWRJbnZhbGlkID0gdGhpcy5maW5kRmlyc3RJbnZhbGlkQ29udHJvbChjb250cm9sLCBmdWxsQ29udHJvbE5hbWUpO1xuICAgICAgICBpZiAobmVzdGVkSW52YWxpZCkge1xuICAgICAgICAgIHJldHVybiBuZXN0ZWRJbnZhbGlkO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGNvbnRyb2wgaXMgaW52YWxpZFxuICAgICAgICBpZiAoY29udHJvbC5pbnZhbGlkICYmIChjb250cm9sLmRpcnR5IHx8IGNvbnRyb2wudG91Y2hlZCkpIHtcbiAgICAgICAgICByZXR1cm4geyBuYW1lOiBmdWxsQ29udHJvbE5hbWUsIGNvbnRyb2wgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGZvcm0gZmllbGQgZWxlbWVudCBieSB2YXJpb3VzIHNlbGVjdG9yc1xuICAgKi9cbiAgcHJpdmF0ZSBmaW5kRm9ybUZpZWxkRWxlbWVudChmaWVsZE5hbWU6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgaWYgKCFmaWVsZE5hbWUpIHJldHVybiBudWxsO1xuICAgIFxuICAgIC8vIENsZWFuIHRoZSBmaWVsZCBuYW1lIGZvciBiZXR0ZXIgbWF0Y2hpbmdcbiAgICBjb25zdCBjbGVhbkZpZWxkTmFtZSA9IGZpZWxkTmFtZS5yZXBsYWNlKC9bLlxcW1xcXV0vZywgJycpO1xuICAgIFxuICAgIC8vIFRyeSB2YXJpb3VzIHNlbGVjdG9ycyB0byBmaW5kIHRoZSBmb3JtIGZpZWxkXG4gICAgY29uc3Qgc2VsZWN0b3JzID0gW1xuICAgICAgLy8gRm9ybWx5IHNwZWNpZmljIHNlbGVjdG9yc1xuICAgICAgYGZvcm1seS1maWVsZFtuZy1yZWZsZWN0LWZpZWxkKj1cIiR7ZmllbGROYW1lfVwiXWAsXG4gICAgICBgZm9ybWx5LWZpZWxkW25nLXJlZmxlY3QtZmllbGQqPVwiJHtjbGVhbkZpZWxkTmFtZX1cIl1gLFxuICAgICAgYFtkYXRhLWN5PVwiJHtmaWVsZE5hbWV9XCJdYCxcbiAgICAgIGBbZGF0YS1jeT1cIiR7Y2xlYW5GaWVsZE5hbWV9XCJdYCxcbiAgICAgIFxuICAgICAgLy8gRm9ybSBjb250cm9sIHNlbGVjdG9yc1xuICAgICAgYGlucHV0W2Zvcm1jb250cm9sbmFtZT1cIiR7ZmllbGROYW1lfVwiXWAsXG4gICAgICBgc2VsZWN0W2Zvcm1jb250cm9sbmFtZT1cIiR7ZmllbGROYW1lfVwiXWAsXG4gICAgICBgdGV4dGFyZWFbZm9ybWNvbnRyb2xuYW1lPVwiJHtmaWVsZE5hbWV9XCJdYCxcbiAgICAgIGBpbnB1dFtmb3JtY29udHJvbG5hbWU9XCIke2NsZWFuRmllbGROYW1lfVwiXWAsXG4gICAgICBgc2VsZWN0W2Zvcm1jb250cm9sbmFtZT1cIiR7Y2xlYW5GaWVsZE5hbWV9XCJdYCxcbiAgICAgIGB0ZXh0YXJlYVtmb3JtY29udHJvbG5hbWU9XCIke2NsZWFuRmllbGROYW1lfVwiXWAsXG4gICAgICBcbiAgICAgIC8vIE5hbWUgYW5kIElEIHNlbGVjdG9yc1xuICAgICAgYGlucHV0W25hbWU9XCIke2ZpZWxkTmFtZX1cIl1gLFxuICAgICAgYHNlbGVjdFtuYW1lPVwiJHtmaWVsZE5hbWV9XCJdYCxcbiAgICAgIGB0ZXh0YXJlYVtuYW1lPVwiJHtmaWVsZE5hbWV9XCJdYCxcbiAgICAgIGAjJHtmaWVsZE5hbWV9YCxcbiAgICAgIGAjJHtjbGVhbkZpZWxkTmFtZX1gLFxuICAgICAgXG4gICAgICAvLyBDbGFzcyBzZWxlY3RvcnNcbiAgICAgIGAuZmllbGQtJHtmaWVsZE5hbWV9YCxcbiAgICAgIGAuZmllbGQtJHtjbGVhbkZpZWxkTmFtZX1gLFxuICAgICAgXG4gICAgICAvLyBBbmd1bGFyIE1hdGVyaWFsIHNwZWNpZmljXG4gICAgICBgbWF0LWZvcm0tZmllbGQ6aGFzKGlucHV0W2Zvcm1jb250cm9sbmFtZT1cIiR7ZmllbGROYW1lfVwiXSlgLFxuICAgICAgYG1hdC1mb3JtLWZpZWxkOmhhcyhzZWxlY3RbZm9ybWNvbnRyb2xuYW1lPVwiJHtmaWVsZE5hbWV9XCJdKWAsXG4gICAgICBgbWF0LWZvcm0tZmllbGQ6aGFzKHRleHRhcmVhW2Zvcm1jb250cm9sbmFtZT1cIiR7ZmllbGROYW1lfVwiXSlgLFxuICAgICAgXG4gICAgICAvLyBHZW5lcmljIGVycm9yIGNsYXNzIHNlbGVjdG9yc1xuICAgICAgYC5uZy1pbnZhbGlkW2Zvcm1jb250cm9sbmFtZT1cIiR7ZmllbGROYW1lfVwiXWAsXG4gICAgICBgLm5nLWludmFsaWRbbmFtZT1cIiR7ZmllbGROYW1lfVwiXWAsXG4gICAgICBcbiAgICAgIC8vIEJyb2FkZXIgc2VhcmNoZXNcbiAgICAgIGBbbmctcmVmbGVjdC1uYW1lPVwiJHtmaWVsZE5hbWV9XCJdYCxcbiAgICAgIGBbbmctcmVmbGVjdC1rZXk9XCIke2ZpZWxkTmFtZX1cIl1gXG4gICAgXTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBpZiAoZWxlbWVudCAmJiB0aGlzLmlzRWxlbWVudFZpc2libGUoZWxlbWVudCkpIHtcbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gU29tZSBzZWxlY3RvcnMgbWlnaHQgYmUgaW52YWxpZCwgY29udGludWUgdHJ5aW5nIG90aGVyc1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gRmFsbGJhY2s6IHNlYXJjaCB0aHJvdWdoIGFsbCBlbGVtZW50c1xuICAgIHJldHVybiB0aGlzLmZhbGxiYWNrRWxlbWVudFNlYXJjaChmaWVsZE5hbWUsIGNsZWFuRmllbGROYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGYWxsYmFjayBzZWFyY2ggdGhyb3VnaCBhbGwgZWxlbWVudHNcbiAgICovXG4gIHByaXZhdGUgZmFsbGJhY2tFbGVtZW50U2VhcmNoKGZpZWxkTmFtZTogc3RyaW5nLCBjbGVhbkZpZWxkTmFtZTogc3RyaW5nKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBhbGxFbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBmb3JtbHktZmllbGQsIG1hdC1mb3JtLWZpZWxkJyk7XG4gICAgXG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIEFycmF5LmZyb20oYWxsRWxlbWVudHMpKSB7XG4gICAgICBjb25zdCBodG1sRWxlbWVudCA9IGVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBcbiAgICAgIC8vIENoZWNrIHZhcmlvdXMgYXR0cmlidXRlc1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFtcbiAgICAgICAgJ2Zvcm1jb250cm9sbmFtZScsXG4gICAgICAgICduYW1lJyxcbiAgICAgICAgJ2lkJyxcbiAgICAgICAgJ25nLXJlZmxlY3QtbmFtZScsXG4gICAgICAgICduZy1yZWZsZWN0LWtleScsXG4gICAgICAgICdkYXRhLWN5J1xuICAgICAgXTtcbiAgICAgIFxuICAgICAgZm9yIChjb25zdCBhdHRyIG9mIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgY29uc3QgYXR0clZhbHVlID0gaHRtbEVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHIpO1xuICAgICAgICBpZiAoYXR0clZhbHVlID09PSBmaWVsZE5hbWUgfHwgYXR0clZhbHVlID09PSBjbGVhbkZpZWxkTmFtZSkge1xuICAgICAgICAgIGlmICh0aGlzLmlzRWxlbWVudFZpc2libGUoaHRtbEVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gaHRtbEVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGNsYXNzIG5hbWVzXG4gICAgICBpZiAoaHRtbEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGBmaWVsZC0ke2ZpZWxkTmFtZX1gKSB8fCBcbiAgICAgICAgICBodG1sRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoYGZpZWxkLSR7Y2xlYW5GaWVsZE5hbWV9YCkpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNFbGVtZW50VmlzaWJsZShodG1sRWxlbWVudCkpIHtcbiAgICAgICAgICByZXR1cm4gaHRtbEVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgZWxlbWVudCBpcyB2aXNpYmxlXG4gICAqL1xuICBwcml2YXRlIGlzRWxlbWVudFZpc2libGUoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICAgIFxuICAgIHJldHVybiByZWN0LndpZHRoID4gMCAmJiBcbiAgICAgICAgICAgcmVjdC5oZWlnaHQgPiAwICYmIFxuICAgICAgICAgICBzdHlsZS52aXNpYmlsaXR5ICE9PSAnaGlkZGVuJyAmJiBcbiAgICAgICAgICAgc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnICYmXG4gICAgICAgICAgIHN0eWxlLm9wYWNpdHkgIT09ICcwJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcnkgdG8gZmluZCBhIG1hdGNoaW5nIGludmFsaWQgZmllbGQgd2hlbiBkaXJlY3Qgc2VhcmNoIGZhaWxzXG4gICAqL1xuICBwcml2YXRlIHRyeUZpbmRNYXRjaGluZ0ludmFsaWRGaWVsZChmaWVsZE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIFxuICAgIGNvbnN0IGNsZWFuRmllbGROYW1lID0gZmllbGROYW1lLnJlcGxhY2UoL1suXFxbXFxdXS9nLCAnJyk7XG4gICAgXG4gICAgLy8gR2V0IGFsbCBpbnZhbGlkIGVsZW1lbnRzXG4gICAgY29uc3QgaW52YWxpZEVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLm5nLWludmFsaWQnKTtcbiAgICBcbiAgICAvLyBUcnkgdG8gZmluZCBvbmUgdGhhdCBtYXRjaGVzIG91ciBmaWVsZCBuYW1lXG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIEFycmF5LmZyb20oaW52YWxpZEVsZW1lbnRzKSkge1xuICAgICAgY29uc3QgaHRtbEVsZW1lbnQgPSBlbGVtZW50IGFzIEhUTUxFbGVtZW50O1xuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGludmFsaWQgZWxlbWVudCBtYXRjaGVzIG91ciBmaWVsZFxuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsnZm9ybWNvbnRyb2xuYW1lJywgJ25hbWUnLCAnaWQnLCAnbmctcmVmbGVjdC1uYW1lJywgJ25nLXJlZmxlY3Qta2V5J107XG4gICAgICBmb3IgKGNvbnN0IGF0dHIgb2YgYXR0cmlidXRlcykge1xuICAgICAgICBjb25zdCBhdHRyVmFsdWUgPSBodG1sRWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cik7XG4gICAgICAgIGlmIChhdHRyVmFsdWUgPT09IGZpZWxkTmFtZSB8fCBhdHRyVmFsdWUgPT09IGNsZWFuRmllbGROYW1lKSB7XG4gICAgICAgICAgaWYgKHRoaXMuaXNFbGVtZW50VmlzaWJsZShodG1sRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KGh0bWxFbGVtZW50KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgZm9yIHBhcnRpYWwgbWF0Y2hlcyBpbiBJRHMgKGZvcm1seSBnZW5lcmF0ZXMgSURzIHdpdGggZmllbGQgbmFtZXMpXG4gICAgICBjb25zdCBpZCA9IGh0bWxFbGVtZW50LmdldEF0dHJpYnV0ZSgnaWQnKTtcbiAgICAgIGlmIChpZCAmJiAoaWQuaW5jbHVkZXMoZmllbGROYW1lKSB8fCBpZC5pbmNsdWRlcyhjbGVhbkZpZWxkTmFtZSkpKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRWxlbWVudFZpc2libGUoaHRtbEVsZW1lbnQpKSB7XG4gICAgICAgICAgdGhpcy5zY3JvbGxUb0VsZW1lbnQoaHRtbEVsZW1lbnQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBJZiBubyBtYXRjaGluZyBpbnZhbGlkIGVsZW1lbnQgZm91bmQsIHRyeSBmb3JtbHkgZmllbGQgY29udGFpbmVyc1xuICAgIHRoaXMudHJ5RmluZEZvcm1seUZpZWxkQ29udGFpbmVyKGZpZWxkTmFtZSwgY2xlYW5GaWVsZE5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyeSB0byBmaW5kIGZvcm1seSBmaWVsZCBjb250YWluZXIgYW5kIGxvb2sgZm9yIGludmFsaWQgZWxlbWVudHMgd2l0aGluIGl0XG4gICAqL1xuICBwcml2YXRlIHRyeUZpbmRGb3JtbHlGaWVsZENvbnRhaW5lcihmaWVsZE5hbWU6IHN0cmluZywgY2xlYW5GaWVsZE5hbWU6IHN0cmluZyk6IHZvaWQgeyAgICBcbiAgICBjb25zdCBmb3JtbHlGaWVsZHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdmb3JtbHktZmllbGQnKTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IGZvcm1seUZpZWxkIG9mIEFycmF5LmZyb20oZm9ybWx5RmllbGRzKSkge1xuICAgICAgY29uc3QgZmllbGRFbGVtZW50ID0gZm9ybWx5RmllbGQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgZm9ybWx5IGZpZWxkJ3MgbmctcmVmbGVjdC1maWVsZCBjb250YWlucyBvdXIgZmllbGQgbmFtZVxuICAgICAgY29uc3QgbmdSZWZsZWN0RmllbGQgPSBmaWVsZEVsZW1lbnQuZ2V0QXR0cmlidXRlKCduZy1yZWZsZWN0LWZpZWxkJyk7XG4gICAgICBpZiAobmdSZWZsZWN0RmllbGQgJiYgXG4gICAgICAgICAgKG5nUmVmbGVjdEZpZWxkLmluY2x1ZGVzKGBcImtleVwiOlwiJHtmaWVsZE5hbWV9XCJgKSB8fCBcbiAgICAgICAgICAgbmdSZWZsZWN0RmllbGQuaW5jbHVkZXMoYFwia2V5XCI6XCIke2NsZWFuRmllbGROYW1lfVwiYCkpKSB7XG4gICAgICAgIFxuICAgICAgICBcbiAgICAgICAgLy8gTG9vayBmb3IgaW52YWxpZCBlbGVtZW50cyB3aXRoaW4gdGhpcyBjb250YWluZXJcbiAgICAgICAgY29uc3QgaW52YWxpZEluQ29udGFpbmVyID0gZmllbGRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5uZy1pbnZhbGlkJyk7XG4gICAgICAgIGlmIChpbnZhbGlkSW5Db250YWluZXIgJiYgdGhpcy5pc0VsZW1lbnRWaXNpYmxlKGludmFsaWRJbkNvbnRhaW5lciBhcyBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICB0aGlzLnNjcm9sbFRvRWxlbWVudChpbnZhbGlkSW5Db250YWluZXIgYXMgSFRNTEVsZW1lbnQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gSWYgbm8gaW52YWxpZCBlbGVtZW50LCBzY3JvbGwgdG8gdGhlIGNvbnRhaW5lciBpdHNlbGZcbiAgICAgICAgaWYgKHRoaXMuaXNFbGVtZW50VmlzaWJsZShmaWVsZEVsZW1lbnQpKSB7XG4gICAgICAgICAgdGhpcy5zY3JvbGxUb0VsZW1lbnQoZmllbGRFbGVtZW50KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gTGFzdCByZXNvcnQ6IHNjcm9sbCB0byBmaXJzdCB2aXNpYmxlIGludmFsaWQgZWxlbWVudFxuICAgIGNvbnN0IGludmFsaWRFbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5uZy1pbnZhbGlkJyk7XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIEFycmF5LmZyb20oaW52YWxpZEVsZW1lbnRzKSkge1xuICAgICAgY29uc3QgaHRtbEVsZW1lbnQgPSBlbGVtZW50IGFzIEhUTUxFbGVtZW50O1xuICAgICAgaWYgKHRoaXMuaXNFbGVtZW50VmlzaWJsZShodG1sRWxlbWVudCkpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxUb0VsZW1lbnQoaHRtbEVsZW1lbnQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIGNvbnNvbGUud2Fybihg4p2MIENvdWxkIG5vdCBmaW5kIGFueSBzdWl0YWJsZSBlbGVtZW50IHRvIHNjcm9sbCB0byBmb3IgZmllbGQ6ICR7ZmllbGROYW1lfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjcm9sbCB0byBlbGVtZW50IHdpdGggc21vb3RoIGFuaW1hdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBzY3JvbGxUb0VsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgLy8gRmluZCB0aGUgY2xvc2VzdCBmb3JtIGZpZWxkIGNvbnRhaW5lclxuICAgICAgY29uc3QgZm9ybUZpZWxkQ29udGFpbmVyID0gZWxlbWVudC5jbG9zZXN0KCdtYXQtZm9ybS1maWVsZCwgZm9ybWx5LWZpZWxkLCAuZm9ybS1maWVsZCwgLm1hdC1tZGMtZm9ybS1maWVsZCwgLmZvcm0tZ3JvdXAnKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGNvbnN0IHRhcmdldEVsZW1lbnQgPSBmb3JtRmllbGRDb250YWluZXIgfHwgZWxlbWVudDtcbiAgICAgIFxuICAgICAgLy8gQ2FsY3VsYXRlIG9mZnNldCB0byBzaG93IGVsZW1lbnQgd2l0aCBzb21lIG1hcmdpbiBmcm9tIHRvcFxuICAgICAgY29uc3Qgb2Zmc2V0ID0gMTAwOyAvLyBwaXhlbHMgZnJvbSB0b3AgKGluY3JlYXNlZCBmb3IgYmV0dGVyIHZpc2liaWxpdHkpXG4gICAgICBjb25zdCBlbGVtZW50UG9zaXRpb24gPSB0YXJnZXRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCArIHdpbmRvdy5wYWdlWU9mZnNldDtcbiAgICAgIGNvbnN0IG9mZnNldFBvc2l0aW9uID0gTWF0aC5tYXgoMCwgZWxlbWVudFBvc2l0aW9uIC0gb2Zmc2V0KTtcbiAgICAgIFxuICAgICAgLy8gVXNlIG11bHRpcGxlIHNjcm9sbCBtZXRob2RzIGZvciBiZXR0ZXIgY29tcGF0aWJpbGl0eVxuICAgICAgdGhpcy5wZXJmb3JtU2Nyb2xsKG9mZnNldFBvc2l0aW9uLCBlbGVtZW50KTsgLy8gUGFzcyB0aGUgb3JpZ2luYWwgZWxlbWVudCBmb3IgZm9jdXNpbmdcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBzY3JvbGxpbmcgdG8gZWxlbWVudDonLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gdGhlIGFjdHVhbCBzY3JvbGwgd2l0aCBtdWx0aXBsZSBtZXRob2RzXG4gICAqL1xuICBwcml2YXRlIHBlcmZvcm1TY3JvbGwodGFyZ2V0UG9zaXRpb246IG51bWJlciwgZWxlbWVudFRvRm9jdXM6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgLy8gTWV0aG9kIDE6IE1vZGVybiBzbW9vdGggc2Nyb2xsXG4gICAgdHJ5IHtcbiAgICAgIHdpbmRvdy5zY3JvbGxUbyh7XG4gICAgICAgIHRvcDogdGFyZ2V0UG9zaXRpb24sXG4gICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJ1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhbGxiYWNrIGZvciBvbGRlciBicm93c2Vyc1xuICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHRhcmdldFBvc2l0aW9uKTtcbiAgICB9XG4gICAgXG4gICAgLy8gTWV0aG9kIDI6IFNjcm9sbEludG9WaWV3IGFzIGJhY2t1cFxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZWxlbWVudFRvRm9jdXMuc2Nyb2xsSW50b1ZpZXcoe1xuICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcbiAgICAgICAgICBibG9jazogJ2NlbnRlcicsXG4gICAgICAgICAgaW5saW5lOiAnbmVhcmVzdCdcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBGYWxsYmFjayBmb3Igb2xkZXIgYnJvd3NlcnNcbiAgICAgICAgZWxlbWVudFRvRm9jdXMuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgIH1cbiAgICB9LCAxMDApO1xuICAgIFxuICAgIC8vIE1ldGhvZCAzOiBGb2N1cyB3aXRoIGRlbGF5IHRvIGVuc3VyZSBzY3JvbGwgY29tcGxldGlvblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5mb2N1c0VsZW1lbnQoZWxlbWVudFRvRm9jdXMpO1xuICAgIH0sIDYwMCk7IC8vIFdhaXQgZm9yIHNjcm9sbCBhbmltYXRpb24gdG8gY29tcGxldGVcbiAgfVxuXG4gIC8qKlxuICAgKiBGb2N1cyBvbiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICovXG4gIHByaXZhdGUgZm9jdXNFbGVtZW50KHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIFxuICAgICAgLy8gSWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGRpcmVjdGx5IGZvY3VzYWJsZSBhbmQgaW52YWxpZCwgZm9jdXMgaXRcbiAgICAgIGlmICh0YXJnZXRFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnbmctaW52YWxpZCcpICYmIFxuICAgICAgICAgICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fCBcbiAgICAgICAgICAgdGFyZ2V0RWxlbWVudCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50IHx8IFxuICAgICAgICAgICB0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCkpIHtcbiAgICAgICAgdGFyZ2V0RWxlbWVudC5mb2N1cygpO1xuICAgICAgICBcbiAgICAgICAgLy8gRm9yIGlucHV0IGVsZW1lbnRzLCBhbHNvIHNlbGVjdCB0aGUgdGV4dFxuICAgICAgICBpZiAodGFyZ2V0RWxlbWVudCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiYgdGFyZ2V0RWxlbWVudC50eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICB0YXJnZXRFbGVtZW50LnNlbGVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gTG9vayBmb3IgaW52YWxpZCBmb2N1c2FibGUgZWxlbWVudHMgd2l0aGluIHRoZSB0YXJnZXRcbiAgICAgIGNvbnN0IGludmFsaWRGb2N1c2FibGVTZWxlY3RvcnMgPSBbXG4gICAgICAgICdpbnB1dC5uZy1pbnZhbGlkOm5vdChbZGlzYWJsZWRdKTpub3QoW3JlYWRvbmx5XSknLFxuICAgICAgICAnc2VsZWN0Lm5nLWludmFsaWQ6bm90KFtkaXNhYmxlZF0pJyxcbiAgICAgICAgJ3RleHRhcmVhLm5nLWludmFsaWQ6bm90KFtkaXNhYmxlZF0pOm5vdChbcmVhZG9ubHldKScsXG4gICAgICAgICdtYXQtcmFkaW8tZ3JvdXAubmctaW52YWxpZCcsXG4gICAgICAgICdtYXQtY2hlY2tib3gubmctaW52YWxpZCdcbiAgICAgIF07XG4gICAgICBcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgaW52YWxpZEZvY3VzYWJsZVNlbGVjdG9ycykge1xuICAgICAgICBjb25zdCBmb2N1c2FibGVFbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKGZvY3VzYWJsZUVsZW1lbnQgJiYgdGhpcy5pc0VsZW1lbnRWaXNpYmxlKGZvY3VzYWJsZUVsZW1lbnQpKSB7XG4gICAgICAgICAgZm9jdXNhYmxlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIEZvciBpbnB1dCBlbGVtZW50cywgYWxzbyBzZWxlY3QgdGhlIHRleHRcbiAgICAgICAgICBpZiAoZm9jdXNhYmxlRWxlbWVudCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiYgZm9jdXNhYmxlRWxlbWVudC50eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICAgIGZvY3VzYWJsZUVsZW1lbnQuc2VsZWN0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBJZiBubyBpbnZhbGlkIGVsZW1lbnRzIGZvdW5kLCBsb29rIGZvciBhbnkgZm9jdXNhYmxlIGVsZW1lbnRzXG4gICAgICBjb25zdCBmb2N1c2FibGVTZWxlY3RvcnMgPSBbXG4gICAgICAgICdpbnB1dDpub3QoW2Rpc2FibGVkXSk6bm90KFtyZWFkb25seV0pJyxcbiAgICAgICAgJ3NlbGVjdDpub3QoW2Rpc2FibGVkXSknLFxuICAgICAgICAndGV4dGFyZWE6bm90KFtkaXNhYmxlZF0pOm5vdChbcmVhZG9ubHldKScsXG4gICAgICAgICdidXR0b246bm90KFtkaXNhYmxlZF0pJyxcbiAgICAgICAgJ21hdC1yYWRpby1ncm91cCcsXG4gICAgICAgICdtYXQtY2hlY2tib3gnLFxuICAgICAgICAnW3RhYmluZGV4PVwiMFwiXSdcbiAgICAgIF07XG4gICAgICBcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgZm9jdXNhYmxlU2VsZWN0b3JzKSB7XG4gICAgICAgIGNvbnN0IGZvY3VzYWJsZUVsZW1lbnQgPSB0YXJnZXRFbGVtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBpZiAoZm9jdXNhYmxlRWxlbWVudCAmJiB0aGlzLmlzRWxlbWVudFZpc2libGUoZm9jdXNhYmxlRWxlbWVudCkpIHtcbiAgICAgICAgICBmb2N1c2FibGVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gRm9yIGlucHV0IGVsZW1lbnRzLCBhbHNvIHNlbGVjdCB0aGUgdGV4dFxuICAgICAgICAgIGlmIChmb2N1c2FibGVFbGVtZW50IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJiBmb2N1c2FibGVFbGVtZW50LnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICAgICAgZm9jdXNhYmxlRWxlbWVudC5zZWxlY3QoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIElmIG5vIGZvY3VzYWJsZSBlbGVtZW50IGZvdW5kLCB0cnkgdG8gZm9jdXMgdGhlIHRhcmdldCBpdHNlbGZcbiAgICAgIGlmICh0YXJnZXRFbGVtZW50LnRhYkluZGV4ID49IDApIHtcbiAgICAgICAgdGFyZ2V0RWxlbWVudC5mb2N1cygpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBmb2N1c2luZyBlbGVtZW50OicsIGVycm9yKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVidWcgbG9nIGFsbCBmb3JtIGVsZW1lbnRzIGZvciB0cm91Ymxlc2hvb3RpbmdcbiAgICovXG4gIGRlYnVnTG9nRm9ybUVsZW1lbnRzKCk6IHZvaWQge1xuICAgIGNvbnNvbGUuZ3JvdXAoJ/CfkJsgRm9ybSBFbGVtZW50cyBEZWJ1ZycpO1xuICAgIFxuICAgIGNvbnN0IGZvcm1FbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBmb3JtbHktZmllbGQnKTtcbiAgICBcbiAgICBmb3JtRWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGh0bWxFbGVtZW50ID0gZWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgICB9KTtcbiAgICBcbiAgICBjb25zdCBpbnZhbGlkRWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubmctaW52YWxpZCcpO1xuICAgIFxuICAgIGNvbnNvbGUuZ3JvdXBFbmQoKTtcbiAgfVxufSAiXX0=
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Injectable } from "@angular/core";
|
|
2
|
+
import { Utils } from "../others/utils";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class TranslationService {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.dictionary = {};
|
|
7
|
+
}
|
|
8
|
+
setLabels(labels) {
|
|
9
|
+
labels?.forEach((label) => {
|
|
10
|
+
this.dictionary[label.labelName] = label.labelValue;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
translate(key, args) {
|
|
14
|
+
var translated = this.dictionary[key] ?? key;
|
|
15
|
+
if (args?.length > 0) {
|
|
16
|
+
translated = Utils.formatString(translated, args);
|
|
17
|
+
}
|
|
18
|
+
return translated;
|
|
19
|
+
}
|
|
20
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationService, providedIn: 'root' }); }
|
|
22
|
+
}
|
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationService, decorators: [{
|
|
24
|
+
type: Injectable,
|
|
25
|
+
args: [{ providedIn: 'root' }]
|
|
26
|
+
}], ctorParameters: () => [] });
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29yaWdpbi1mb3JtL3NyYy9saWIvc2VydmljZXMvdHJhbnNsYXRpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFHeEMsTUFBTSxPQUFPLGtCQUFrQjtJQUc3QjtRQUZRLGVBQVUsR0FBOEIsRUFBRSxDQUFDO0lBRW5DLENBQUM7SUFFakIsU0FBUyxDQUFDLE1BQWU7UUFDdkIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3hCLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQVcsRUFBRSxJQUFVO1FBQy9CLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDO1FBQzdDLElBQUksSUFBSSxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyQixVQUFVLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FDN0IsVUFBVSxFQUNWLElBQUksQ0FDTCxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7K0dBcEJVLGtCQUFrQjttSEFBbEIsa0JBQWtCLGNBREwsTUFBTTs7NEZBQ25CLGtCQUFrQjtrQkFEOUIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IExhYmVsIH0gZnJvbSBcIi4uL21vZGVscy9sYWJlbC5tb2RlbFwiO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tIFwiLi4vb3RoZXJzL3V0aWxzXCI7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBkaWN0aW9uYXJ5OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG5cbiAgY29uc3RydWN0b3IoKSB7IH1cblxuICBzZXRMYWJlbHMobGFiZWxzOiBMYWJlbFtdKSB7XG4gICAgbGFiZWxzPy5mb3JFYWNoKChsYWJlbCkgPT4ge1xuICAgICAgdGhpcy5kaWN0aW9uYXJ5W2xhYmVsLmxhYmVsTmFtZV0gPSBsYWJlbC5sYWJlbFZhbHVlO1xuICAgIH0pO1xuICB9XG5cbiAgdHJhbnNsYXRlKGtleTogc3RyaW5nLCBhcmdzPzogYW55KTogc3RyaW5nIHtcbiAgICB2YXIgdHJhbnNsYXRlZCA9IHRoaXMuZGljdGlvbmFyeVtrZXldID8/IGtleTtcbiAgICBpZiAoYXJncz8ubGVuZ3RoID4gMCkge1xuICAgICAgdHJhbnNsYXRlZCA9IFV0aWxzLmZvcm1hdFN0cmluZyhcbiAgICAgICAgdHJhbnNsYXRlZCxcbiAgICAgICAgYXJnc1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRyYW5zbGF0ZWQ7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Component, Inject } from '@angular/core';
|
|
2
|
+
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
3
|
+
import { LabelKeys } from '../enums/label.keys';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/material/dialog";
|
|
6
|
+
import * as i2 from "@angular/material/card";
|
|
7
|
+
import * as i3 from "@angular/material/button";
|
|
8
|
+
import * as i4 from "../others/translation.pipe";
|
|
9
|
+
export class ConfirmationComponent {
|
|
10
|
+
constructor(data, dialog) {
|
|
11
|
+
this.data = data;
|
|
12
|
+
this.dialog = dialog;
|
|
13
|
+
this.commonKeys = LabelKeys.common;
|
|
14
|
+
this.item = data.item;
|
|
15
|
+
this.text = data.text;
|
|
16
|
+
}
|
|
17
|
+
ngOnInit() { }
|
|
18
|
+
submit() {
|
|
19
|
+
this.dialog.close({ event: 'submit', item: this.item });
|
|
20
|
+
}
|
|
21
|
+
cancel() {
|
|
22
|
+
this.dialog.close({ event: 'cancel' });
|
|
23
|
+
}
|
|
24
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmationComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
25
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ConfirmationComponent, selector: "app-confirmation", ngImport: i0, template: "<mat-card class=\"cardWithShadow blue_theme theme-card m-b-0\">\n <mat-card-header>\n <mat-card-title class=\"m-b-0\">\n {{ commonKeys.confirmation.title | translate }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"b-t-1\">\n {{ text | translate }}\n <div class=\"m-t-24\">\n <button mat-flat-button type=\"button\" (click)=\"submit()\" color=\"primary\" class=\"m-r-16\">\n {{ commonKeys.actions.confirm | translate }}\n </button>\n <button mat-flat-button type=\"button\" (click)=\"cancel()\">\n {{ commonKeys.actions.cancel | translate }}\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: [""], dependencies: [{ kind: "component", type: i2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i2.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i2.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] }); }
|
|
26
|
+
}
|
|
27
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmationComponent, decorators: [{
|
|
28
|
+
type: Component,
|
|
29
|
+
args: [{ selector: 'app-confirmation', template: "<mat-card class=\"cardWithShadow blue_theme theme-card m-b-0\">\n <mat-card-header>\n <mat-card-title class=\"m-b-0\">\n {{ commonKeys.confirmation.title | translate }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"b-t-1\">\n {{ text | translate }}\n <div class=\"m-t-24\">\n <button mat-flat-button type=\"button\" (click)=\"submit()\" color=\"primary\" class=\"m-r-16\">\n {{ commonKeys.actions.confirm | translate }}\n </button>\n <button mat-flat-button type=\"button\" (click)=\"cancel()\">\n {{ commonKeys.actions.cancel | translate }}\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n" }]
|
|
30
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
31
|
+
type: Inject,
|
|
32
|
+
args: [MAT_DIALOG_DATA]
|
|
33
|
+
}] }, { type: i1.MatDialogRef }] });
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlybWF0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29yaWdpbi1mb3JtL3NyYy9saWIvc2hhcmVkLWNvbXBvbmVudHMvY29uZmlybWF0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29yaWdpbi1mb3JtL3NyYy9saWIvc2hhcmVkLWNvbXBvbmVudHMvY29uZmlybWF0aW9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFBRSxlQUFlLEVBQWdCLE1BQU0sMEJBQTBCLENBQUM7QUFDekUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7QUFPaEQsTUFBTSxPQUFPLHFCQUFxQjtJQU1oQyxZQUNtQyxJQUFpQyxFQUMzRCxNQUEyQztRQURqQixTQUFJLEdBQUosSUFBSSxDQUE2QjtRQUMzRCxXQUFNLEdBQU4sTUFBTSxDQUFxQztRQVA3QyxlQUFVLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztRQVNuQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxRQUFRLEtBQVUsQ0FBQztJQUVuQixNQUFNO1FBQ0osSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQzsrR0F0QlUscUJBQXFCLGtCQU90QixlQUFlO21HQVBkLHFCQUFxQix3RENUbEMsMHFCQWtCQTs7NEZEVGEscUJBQXFCO2tCQUxqQyxTQUFTOytCQUNFLGtCQUFrQjs7MEJBV3pCLE1BQU07MkJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5qZWN0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nUmVmIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IExhYmVsS2V5cyB9IGZyb20gJy4uL2VudW1zL2xhYmVsLmtleXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtY29uZmlybWF0aW9uJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NvbmZpcm1hdGlvbi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NvbmZpcm1hdGlvbi5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBDb25maXJtYXRpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwdWJsaWMgY29tbW9uS2V5cyA9IExhYmVsS2V5cy5jb21tb247XG5cbiAgaXRlbTogYW55O1xuICB0ZXh0OiBhbnk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHByaXZhdGUgZGF0YTogeyBpdGVtOiBhbnk7IHRleHQ6IHN0cmluZyB9LFxuICAgIHB1YmxpYyBkaWFsb2c6IE1hdERpYWxvZ1JlZjxDb25maXJtYXRpb25Db21wb25lbnQ+XG4gICkge1xuICAgIHRoaXMuaXRlbSA9IGRhdGEuaXRlbTtcbiAgICB0aGlzLnRleHQgPSBkYXRhLnRleHQ7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHt9XG5cbiAgc3VibWl0KCk6IHZvaWQge1xuICAgIHRoaXMuZGlhbG9nLmNsb3NlKHsgZXZlbnQ6ICdzdWJtaXQnLCBpdGVtOiB0aGlzLml0ZW0gfSk7XG4gIH1cblxuICBjYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5kaWFsb2cuY2xvc2UoeyBldmVudDogJ2NhbmNlbCcgfSk7XG4gIH1cbn1cbiIsIjxtYXQtY2FyZCBjbGFzcz1cImNhcmRXaXRoU2hhZG93IGJsdWVfdGhlbWUgdGhlbWUtY2FyZCBtLWItMFwiPlxuICA8bWF0LWNhcmQtaGVhZGVyPlxuICAgIDxtYXQtY2FyZC10aXRsZSBjbGFzcz1cIm0tYi0wXCI+XG4gICAgICB7eyBjb21tb25LZXlzLmNvbmZpcm1hdGlvbi50aXRsZSB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvbWF0LWNhcmQtdGl0bGU+XG4gIDwvbWF0LWNhcmQtaGVhZGVyPlxuICA8bWF0LWNhcmQtY29udGVudCBjbGFzcz1cImItdC0xXCI+XG4gICAge3sgdGV4dCB8IHRyYW5zbGF0ZSB9fVxuICAgIDxkaXYgY2xhc3M9XCJtLXQtMjRcIj5cbiAgICAgIDxidXR0b24gbWF0LWZsYXQtYnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwic3VibWl0KClcIiBjb2xvcj1cInByaW1hcnlcIiBjbGFzcz1cIm0tci0xNlwiPlxuICAgICAgICB7eyBjb21tb25LZXlzLmFjdGlvbnMuY29uZmlybSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uIG1hdC1mbGF0LWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNhbmNlbCgpXCI+XG4gICAgICAgIHt7IGNvbW1vbktleXMuYWN0aW9ucy5jYW5jZWwgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L21hdC1jYXJkLWNvbnRlbnQ+XG48L21hdC1jYXJkPlxuIl19
|