valtech-components 2.0.1007 → 2.0.1008

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 (43) hide show
  1. package/esm2022/lib/components/molecules/comment/comment.component.mjs +3 -3
  2. package/esm2022/lib/components/organisms/organization-view/organization-view.component.mjs +3 -141
  3. package/esm2022/lib/components/organisms/organization-view/organization-view.i18n.mjs +1 -21
  4. package/esm2022/lib/components/organisms/profile-view/profile-view.component.mjs +6 -16
  5. package/esm2022/lib/components/templates/auth-background/auth-background.component.mjs +19 -17
  6. package/esm2022/lib/services/auth/auth.service.mjs +1 -14
  7. package/esm2022/lib/services/auth/types.mjs +1 -1
  8. package/esm2022/lib/services/org/org.service.mjs +1 -8
  9. package/esm2022/lib/services/org/types.mjs +1 -1
  10. package/esm2022/lib/services/preferences/preferences.service.mjs +36 -11
  11. package/esm2022/lib/version.mjs +2 -2
  12. package/esm2022/public-api.mjs +1 -7
  13. package/fesm2022/valtech-components.mjs +370 -1905
  14. package/fesm2022/valtech-components.mjs.map +1 -1
  15. package/lib/components/organisms/organization-view/organization-view.component.d.ts +0 -6
  16. package/lib/components/templates/auth-background/auth-background.component.d.ts +2 -2
  17. package/lib/services/auth/auth.service.d.ts +1 -7
  18. package/lib/services/auth/types.d.ts +0 -23
  19. package/lib/services/org/org.service.d.ts +1 -6
  20. package/lib/services/org/types.d.ts +0 -30
  21. package/lib/version.d.ts +1 -1
  22. package/package.json +1 -1
  23. package/public-api.d.ts +1 -8
  24. package/esm2022/lib/components/organisms/about-view/about-view.component.mjs +0 -436
  25. package/esm2022/lib/components/organisms/about-view/about-view.i18n.mjs +0 -61
  26. package/esm2022/lib/components/organisms/about-view/about.routes.mjs +0 -36
  27. package/esm2022/lib/components/organisms/about-view/types.mjs +0 -19
  28. package/esm2022/lib/components/organisms/api-keys-modal/api-keys-modal.component.mjs +0 -385
  29. package/esm2022/lib/components/organisms/api-keys-modal/api-keys-modal.i18n.mjs +0 -63
  30. package/esm2022/lib/components/organisms/member-import-modal/member-import-modal.component.mjs +0 -313
  31. package/esm2022/lib/components/organisms/member-import-modal/member-import-modal.i18n.mjs +0 -63
  32. package/esm2022/lib/services/apikeys/api-keys.service.mjs +0 -46
  33. package/esm2022/lib/services/apikeys/types.mjs +0 -7
  34. package/lib/components/organisms/about-view/about-view.component.d.ts +0 -88
  35. package/lib/components/organisms/about-view/about-view.i18n.d.ts +0 -14
  36. package/lib/components/organisms/about-view/about.routes.d.ts +0 -31
  37. package/lib/components/organisms/about-view/types.d.ts +0 -76
  38. package/lib/components/organisms/api-keys-modal/api-keys-modal.component.d.ts +0 -44
  39. package/lib/components/organisms/api-keys-modal/api-keys-modal.i18n.d.ts +0 -6
  40. package/lib/components/organisms/member-import-modal/member-import-modal.component.d.ts +0 -47
  41. package/lib/components/organisms/member-import-modal/member-import-modal.i18n.d.ts +0 -6
  42. package/lib/services/apikeys/api-keys.service.d.ts +0 -25
  43. package/lib/services/apikeys/types.d.ts +0 -46
@@ -1,313 +0,0 @@
1
- import { Component, computed, inject, Input, signal } from '@angular/core';
2
- import { FormsModule } from '@angular/forms';
3
- import { IonButton, IonButtons, IonCheckbox, IonContent, IonHeader, IonSelect, IonSelectOption, IonSpinner, IonTextarea, IonToolbar, } from '@ionic/angular/standalone';
4
- import { DisplayComponent } from '../../atoms/display/display.component';
5
- import { TextComponent } from '../../atoms/text/text.component';
6
- import { TitleComponent } from '../../atoms/title/title.component';
7
- import { I18nService } from '../../../services/i18n';
8
- import { OrgService } from '../../../services/org/org.service';
9
- import { MEMBER_IMPORT_MODAL_I18N } from './member-import-modal.i18n';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/forms";
12
- const DEFAULT_NAMESPACE = 'Settings.ImportModal';
13
- /**
14
- * `val-member-import-modal` — panel de carga masiva de miembros (ADR-023 fase 6).
15
- *
16
- * El admin pega un CSV (`email,nombre,rol`); el modal lo parsea a filas y llama
17
- * `OrgService.importMembers`. Muestra el resultado por-fila (partial success):
18
- * `created` / `assigned` / `skipped` / `error`. Header canónico (Regla #5).
19
- *
20
- * Auto-registra defaults i18n (es/en) en `Settings.ImportModal`.
21
- */
22
- export class MemberImportModalComponent {
23
- constructor() {
24
- this.i18n = inject(I18nService);
25
- this.orgService = inject(OrgService);
26
- /** Org destino del import. */
27
- this.orgId = '';
28
- /** Nombres de roles disponibles (para el hint). Opcional. */
29
- this.availableRoles = [];
30
- /** Namespace i18n. */
31
- this.i18nNamespace = DEFAULT_NAMESPACE;
32
- this.csv = '';
33
- this.onConflict = 'assignRole';
34
- this.sendActivation = true;
35
- this.submitting = signal(false);
36
- this.errorMsg = signal('');
37
- this.results = signal(null);
38
- this.rolesHint = computed(() => this.availableRoles.length ? `${this.t('rolesAvailable')} ${this.availableRoles.join(', ')}` : '');
39
- this.summaryLabel = computed(() => {
40
- const s = this.results()?.summary;
41
- if (!s)
42
- return this.t('summary');
43
- return `${this.t('summary')}: ${s.created} ${this.t('created')} · ${s.assigned} ${this.t('assigned')} · ${s.skipped} ${this.t('skipped')} · ${s.failed} ${this.t('failed')}`;
44
- });
45
- if (!this.i18n.hasNamespace(DEFAULT_NAMESPACE)) {
46
- this.i18n.registerContent(DEFAULT_NAMESPACE, MEMBER_IMPORT_MODAL_I18N);
47
- }
48
- }
49
- ngOnInit() {
50
- if (!this.i18n.hasNamespace(this.i18nNamespace)) {
51
- this.i18n.registerContent(this.i18nNamespace, MEMBER_IMPORT_MODAL_I18N);
52
- }
53
- }
54
- /** Parsea el CSV pegado a filas {email,name,roleName}. Tolera header. */
55
- parseCsv() {
56
- const rows = [];
57
- for (const raw of this.csv.split(/\r?\n/)) {
58
- const line = raw.trim();
59
- if (!line)
60
- continue;
61
- const cols = line.split(',').map(c => c.trim());
62
- const email = (cols[0] ?? '').toLowerCase();
63
- // Saltar header (primera col "email") o líneas sin @.
64
- if (!email || !email.includes('@'))
65
- continue;
66
- rows.push({ email, name: cols[1] ?? '', roleName: cols[2] ?? '' });
67
- }
68
- return rows;
69
- }
70
- submit() {
71
- this.errorMsg.set('');
72
- const users = this.parseCsv();
73
- if (users.length === 0) {
74
- this.errorMsg.set(this.t('noRows'));
75
- return;
76
- }
77
- if (users.some(u => !u.roleName)) {
78
- this.errorMsg.set(this.t('parseError'));
79
- return;
80
- }
81
- this.submitting.set(true);
82
- this.orgService
83
- .importMembers(this.orgId, {
84
- users,
85
- onConflict: this.onConflict,
86
- sendActivation: this.sendActivation,
87
- })
88
- .subscribe({
89
- next: res => {
90
- this.submitting.set(false);
91
- this.results.set(res);
92
- // Refrescar lista del consumer si hubo altas/asignaciones efectivas.
93
- if (res.summary.created + res.summary.assigned > 0) {
94
- this.onSuccess?.();
95
- }
96
- },
97
- error: err => {
98
- this.submitting.set(false);
99
- this.errorMsg.set(err?.error?.message ?? this.t('genericError'));
100
- },
101
- });
102
- }
103
- statusLabel(r) {
104
- const base = this.t(r.status === 'error' ? 'failed' : r.status);
105
- if (r.status === 'created' && r.activation) {
106
- return `${base} · ${this.t(r.activation === 'sent' ? 'activationSent' : 'activationPending')}`;
107
- }
108
- return base;
109
- }
110
- reset() {
111
- this.csv = '';
112
- this.errorMsg.set('');
113
- this.results.set(null);
114
- }
115
- dismiss() {
116
- this._modalRef?.dismiss(null, 'cancel');
117
- }
118
- t(key) {
119
- return this.i18n.t(key, this.i18nNamespace);
120
- }
121
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MemberImportModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
122
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MemberImportModalComponent, isStandalone: true, selector: "val-member-import-modal", inputs: { orgId: "orgId", availableRoles: "availableRoles", onSuccess: "onSuccess", _modalRef: "_modalRef", i18nNamespace: "i18nNamespace" }, ngImport: i0, template: `
123
- <ion-header>
124
- <ion-toolbar>
125
- <ion-buttons slot="end">
126
- <ion-button fill="clear" color="dark" (click)="dismiss()">
127
- <strong>{{ t('close') }}</strong>
128
- </ion-button>
129
- </ion-buttons>
130
- </ion-toolbar>
131
- </ion-header>
132
-
133
- <ion-content class="ion-padding">
134
- <val-display [props]="{ content: t('title'), size: 'small', color: 'dark' }" />
135
-
136
- @if (!results()) {
137
- <val-title [props]="{ content: t('hint'), size: 'large', color: '', bold: false }" />
138
-
139
- @if (rolesHint()) {
140
- <val-text [props]="{ content: rolesHint(), size: 'small', color: 'medium', bold: false }" />
141
- }
142
-
143
- <ion-textarea
144
- class="import-csv"
145
- [autoGrow]="true"
146
- [rows]="6"
147
- [placeholder]="t('csvPlaceholder')"
148
- [(ngModel)]="csv"
149
- />
150
-
151
- <ion-select
152
- class="import-conflict"
153
- label="{{ t('onConflictLabel') }}"
154
- labelPlacement="stacked"
155
- interface="popover"
156
- [(ngModel)]="onConflict"
157
- >
158
- <ion-select-option value="assignRole">{{ t('conflictAssign') }}</ion-select-option>
159
- <ion-select-option value="skip">{{ t('conflictSkip') }}</ion-select-option>
160
- <ion-select-option value="error">{{ t('conflictError') }}</ion-select-option>
161
- </ion-select>
162
-
163
- <ion-checkbox class="import-activation" labelPlacement="end" [(ngModel)]="sendActivation">
164
- {{ t('sendActivation') }}
165
- </ion-checkbox>
166
-
167
- @if (errorMsg()) {
168
- <p class="import-error">{{ errorMsg() }}</p>
169
- }
170
-
171
- <div class="import-actions">
172
- <ion-button expand="block" color="dark" [disabled]="submitting()" (click)="submit()">
173
- @if (submitting()) {
174
- <ion-spinner name="dots" />
175
- &nbsp;{{ t('submitting') }}
176
- } @else {
177
- {{ t('submit') }}
178
- }
179
- </ion-button>
180
- </div>
181
- } @else {
182
- <!-- Resultados -->
183
- <val-title [props]="{ content: summaryLabel(), size: 'large', color: '', bold: true }" />
184
- <div class="import-results">
185
- @for (r of results()!.results; track r.email) {
186
- <div class="import-row import-row--{{ r.status }}">
187
- <span class="import-row__email">{{ r.email }}</span>
188
- <span class="import-row__status">{{ statusLabel(r) }}</span>
189
- @if (r.reason) {
190
- <span class="import-row__reason">{{ r.reason }}</span>
191
- }
192
- </div>
193
- }
194
- </div>
195
- <div class="import-actions">
196
- <ion-button expand="block" fill="outline" color="dark" (click)="reset()">
197
- {{ t('again') }}
198
- </ion-button>
199
- </div>
200
- }
201
- </ion-content>
202
- `, isInline: true, styles: ["val-display{display:block;margin-bottom:4px}val-title{display:block;margin-bottom:12px}.import-csv{--background: var(--ion-color-light);border-radius:10px;margin-bottom:16px;font-family:monospace;font-size:13px}.import-conflict{margin-bottom:12px}.import-activation{display:block;margin-bottom:16px;font-size:14px}.import-error{margin:0 0 12px;font-size:.875rem;color:var(--ion-color-danger, #c0392b)}.import-actions{margin-top:8px}.import-results{display:flex;flex-direction:column;gap:6px;margin:12px 0}.import-row{display:grid;grid-template-columns:1fr auto;grid-row-gap:2px;align-items:center;padding:10px 12px;border-radius:8px;border-left:3px solid var(--ion-color-medium);background:var(--ion-color-light);font-size:14px}.import-row--created{border-left-color:var(--ion-color-success, #2dd36f)}.import-row--assigned{border-left-color:var(--ion-color-primary, #7026df)}.import-row--skipped{border-left-color:var(--ion-color-medium, #92949c)}.import-row--error{border-left-color:var(--ion-color-danger, #c0392b)}.import-row__email{font-weight:600;color:var(--ion-color-dark)}.import-row__status{text-align:right;color:var(--ion-color-medium-shade, #6b6e76)}.import-row__reason{grid-column:1 / -1;font-size:12px;color:var(--ion-color-danger, #c0392b)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }] }); }
203
- }
204
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MemberImportModalComponent, decorators: [{
205
- type: Component,
206
- args: [{ selector: 'val-member-import-modal', standalone: true, imports: [
207
- FormsModule,
208
- IonHeader,
209
- IonToolbar,
210
- IonButtons,
211
- IonButton,
212
- IonContent,
213
- IonTextarea,
214
- IonSelect,
215
- IonSelectOption,
216
- IonCheckbox,
217
- IonSpinner,
218
- DisplayComponent,
219
- TextComponent,
220
- TitleComponent,
221
- ], template: `
222
- <ion-header>
223
- <ion-toolbar>
224
- <ion-buttons slot="end">
225
- <ion-button fill="clear" color="dark" (click)="dismiss()">
226
- <strong>{{ t('close') }}</strong>
227
- </ion-button>
228
- </ion-buttons>
229
- </ion-toolbar>
230
- </ion-header>
231
-
232
- <ion-content class="ion-padding">
233
- <val-display [props]="{ content: t('title'), size: 'small', color: 'dark' }" />
234
-
235
- @if (!results()) {
236
- <val-title [props]="{ content: t('hint'), size: 'large', color: '', bold: false }" />
237
-
238
- @if (rolesHint()) {
239
- <val-text [props]="{ content: rolesHint(), size: 'small', color: 'medium', bold: false }" />
240
- }
241
-
242
- <ion-textarea
243
- class="import-csv"
244
- [autoGrow]="true"
245
- [rows]="6"
246
- [placeholder]="t('csvPlaceholder')"
247
- [(ngModel)]="csv"
248
- />
249
-
250
- <ion-select
251
- class="import-conflict"
252
- label="{{ t('onConflictLabel') }}"
253
- labelPlacement="stacked"
254
- interface="popover"
255
- [(ngModel)]="onConflict"
256
- >
257
- <ion-select-option value="assignRole">{{ t('conflictAssign') }}</ion-select-option>
258
- <ion-select-option value="skip">{{ t('conflictSkip') }}</ion-select-option>
259
- <ion-select-option value="error">{{ t('conflictError') }}</ion-select-option>
260
- </ion-select>
261
-
262
- <ion-checkbox class="import-activation" labelPlacement="end" [(ngModel)]="sendActivation">
263
- {{ t('sendActivation') }}
264
- </ion-checkbox>
265
-
266
- @if (errorMsg()) {
267
- <p class="import-error">{{ errorMsg() }}</p>
268
- }
269
-
270
- <div class="import-actions">
271
- <ion-button expand="block" color="dark" [disabled]="submitting()" (click)="submit()">
272
- @if (submitting()) {
273
- <ion-spinner name="dots" />
274
- &nbsp;{{ t('submitting') }}
275
- } @else {
276
- {{ t('submit') }}
277
- }
278
- </ion-button>
279
- </div>
280
- } @else {
281
- <!-- Resultados -->
282
- <val-title [props]="{ content: summaryLabel(), size: 'large', color: '', bold: true }" />
283
- <div class="import-results">
284
- @for (r of results()!.results; track r.email) {
285
- <div class="import-row import-row--{{ r.status }}">
286
- <span class="import-row__email">{{ r.email }}</span>
287
- <span class="import-row__status">{{ statusLabel(r) }}</span>
288
- @if (r.reason) {
289
- <span class="import-row__reason">{{ r.reason }}</span>
290
- }
291
- </div>
292
- }
293
- </div>
294
- <div class="import-actions">
295
- <ion-button expand="block" fill="outline" color="dark" (click)="reset()">
296
- {{ t('again') }}
297
- </ion-button>
298
- </div>
299
- }
300
- </ion-content>
301
- `, styles: ["val-display{display:block;margin-bottom:4px}val-title{display:block;margin-bottom:12px}.import-csv{--background: var(--ion-color-light);border-radius:10px;margin-bottom:16px;font-family:monospace;font-size:13px}.import-conflict{margin-bottom:12px}.import-activation{display:block;margin-bottom:16px;font-size:14px}.import-error{margin:0 0 12px;font-size:.875rem;color:var(--ion-color-danger, #c0392b)}.import-actions{margin-top:8px}.import-results{display:flex;flex-direction:column;gap:6px;margin:12px 0}.import-row{display:grid;grid-template-columns:1fr auto;grid-row-gap:2px;align-items:center;padding:10px 12px;border-radius:8px;border-left:3px solid var(--ion-color-medium);background:var(--ion-color-light);font-size:14px}.import-row--created{border-left-color:var(--ion-color-success, #2dd36f)}.import-row--assigned{border-left-color:var(--ion-color-primary, #7026df)}.import-row--skipped{border-left-color:var(--ion-color-medium, #92949c)}.import-row--error{border-left-color:var(--ion-color-danger, #c0392b)}.import-row__email{font-weight:600;color:var(--ion-color-dark)}.import-row__status{text-align:right;color:var(--ion-color-medium-shade, #6b6e76)}.import-row__reason{grid-column:1 / -1;font-size:12px;color:var(--ion-color-danger, #c0392b)}\n"] }]
302
- }], ctorParameters: () => [], propDecorators: { orgId: [{
303
- type: Input
304
- }], availableRoles: [{
305
- type: Input
306
- }], onSuccess: [{
307
- type: Input
308
- }], _modalRef: [{
309
- type: Input
310
- }], i18nNamespace: [{
311
- type: Input
312
- }] } });
313
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLWltcG9ydC1tb2RhbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL21lbWJlci1pbXBvcnQtbW9kYWwvbWVtYmVyLWltcG9ydC1tb2RhbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFdBQVcsRUFDWCxVQUFVLEVBQ1YsU0FBUyxFQUNULFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFdBQVcsRUFDWCxVQUFVLEdBQ1gsTUFBTSwyQkFBMkIsQ0FBQztBQUVuQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFHL0QsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7OztBQUV0RSxNQUFNLGlCQUFpQixHQUFHLHNCQUFzQixDQUFDO0FBRWpEOzs7Ozs7OztHQVFHO0FBbUxILE1BQU0sT0FBTywwQkFBMEI7SUF1Q3JDO1FBdENRLFNBQUksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0IsZUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUV4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LFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csU0FBUztzQkFBakIsS0FBSztnQkFHRyxhQUFhO3NCQUFyQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBjb21wdXRlZCwgaW5qZWN0LCBJbnB1dCwgT25Jbml0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgSW9uQnV0dG9uLFxuICBJb25CdXR0b25zLFxuICBJb25DaGVja2JveCxcbiAgSW9uQ29udGVudCxcbiAgSW9uSGVhZGVyLFxuICBJb25TZWxlY3QsXG4gIElvblNlbGVjdE9wdGlvbixcbiAgSW9uU3Bpbm5lcixcbiAgSW9uVGV4dGFyZWEsXG4gIElvblRvb2xiYXIsXG59IGZyb20gJ0Bpb25pYy9hbmd1bGFyL3N0YW5kYWxvbmUnO1xuXG5pbXBvcnQgeyBEaXNwbGF5Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYXRvbXMvZGlzcGxheS9kaXNwbGF5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUZXh0Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYXRvbXMvdGV4dC90ZXh0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUaXRsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2F0b21zL3RpdGxlL3RpdGxlLmNvbXBvbmVudCc7XG5cbmltcG9ydCB7IEkxOG5TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvaTE4bic7XG5pbXBvcnQgeyBPcmdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvb3JnL29yZy5zZXJ2aWNlJztcbmltcG9ydCB7IEltcG9ydE1lbWJlcnNSZXNwb25zZSwgSW1wb3J0T25Db25mbGljdCwgSW1wb3J0Um93UmVzdWx0LCBJbXBvcnRVc2VyUm93IH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvb3JnL3R5cGVzJztcblxuaW1wb3J0IHsgTUVNQkVSX0lNUE9SVF9NT0RBTF9JMThOIH0gZnJvbSAnLi9tZW1iZXItaW1wb3J0LW1vZGFsLmkxOG4nO1xuXG5jb25zdCBERUZBVUxUX05BTUVTUEFDRSA9ICdTZXR0aW5ncy5JbXBvcnRNb2RhbCc7XG5cbi8qKlxuICogYHZhbC1tZW1iZXItaW1wb3J0LW1vZGFsYCDigJQgcGFuZWwgZGUgY2FyZ2EgbWFzaXZhIGRlIG1pZW1icm9zIChBRFItMDIzIGZhc2UgNikuXG4gKlxuICogRWwgYWRtaW4gcGVnYSB1biBDU1YgKGBlbWFpbCxub21icmUscm9sYCk7IGVsIG1vZGFsIGxvIHBhcnNlYSBhIGZpbGFzIHkgbGxhbWFcbiAqIGBPcmdTZXJ2aWNlLmltcG9ydE1lbWJlcnNgLiBNdWVzdHJhIGVsIHJlc3VsdGFkbyBwb3ItZmlsYSAocGFydGlhbCBzdWNjZXNzKTpcbiAqIGBjcmVhdGVkYCAvIGBhc3NpZ25lZGAgLyBgc2tpcHBlZGAgLyBgZXJyb3JgLiBIZWFkZXIgY2Fuw7NuaWNvIChSZWdsYSAjNSkuXG4gKlxuICogQXV0by1yZWdpc3RyYSBkZWZhdWx0cyBpMThuIChlcy9lbikgZW4gYFNldHRpbmdzLkltcG9ydE1vZGFsYC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndmFsLW1lbWJlci1pbXBvcnQtbW9kYWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgSW9uSGVhZGVyLFxuICAgIElvblRvb2xiYXIsXG4gICAgSW9uQnV0dG9ucyxcbiAgICBJb25CdXR0b24sXG4gICAgSW9uQ29udGVudCxcbiAgICBJb25UZXh0YXJlYSxcbiAgICBJb25TZWxlY3QsXG4gICAgSW9uU2VsZWN0T3B0aW9uLFxuICAgIElvbkNoZWNrYm94LFxuICAgIElvblNwaW5uZXIsXG4gICAgRGlzcGxheUNvbXBvbmVudCxcbiAgICBUZXh0Q29tcG9uZW50LFxuICAgIFRpdGxlQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxpb24taGVhZGVyPlxuICAgICAgPGlvbi10b29sYmFyPlxuICAgICAgICA8aW9uLWJ1dHRvbnMgc2xvdD1cImVuZFwiPlxuICAgICAgICAgIDxpb24tYnV0dG9uIGZpbGw9XCJjbGVhclwiIGNvbG9yPVwiZGFya1wiIChjbGljayk9XCJkaXNtaXNzKClcIj5cbiAgICAgICAgICAgIDxzdHJvbmc+e3sgdCgnY2xvc2UnKSB9fTwvc3Ryb25nPlxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgPC9pb24tYnV0dG9ucz5cbiAgICAgIDwvaW9uLXRvb2xiYXI+XG4gICAgPC9pb24taGVhZGVyPlxuXG4gICAgPGlvbi1jb250ZW50IGNsYXNzPVwiaW9uLXBhZGRpbmdcIj5cbiAgICAgIDx2YWwtZGlzcGxheSBbcHJvcHNdPVwieyBjb250ZW50OiB0KCd0aXRsZScpLCBzaXplOiAnc21hbGwnLCBjb2xvcjogJ2RhcmsnIH1cIiAvPlxuXG4gICAgICBAaWYgKCFyZXN1bHRzKCkpIHtcbiAgICAgICAgPHZhbC10aXRsZSBbcHJvcHNdPVwieyBjb250ZW50OiB0KCdoaW50JyksIHNpemU6ICdsYXJnZScsIGNvbG9yOiAnJywgYm9sZDogZmFsc2UgfVwiIC8+XG5cbiAgICAgICAgQGlmIChyb2xlc0hpbnQoKSkge1xuICAgICAgICAgIDx2YWwtdGV4dCBbcHJvcHNdPVwieyBjb250ZW50OiByb2xlc0hpbnQoKSwgc2l6ZTogJ3NtYWxsJywgY29sb3I6ICdtZWRpdW0nLCBib2xkOiBmYWxzZSB9XCIgLz5cbiAgICAgICAgfVxuXG4gICAgICAgIDxpb24tdGV4dGFyZWFcbiAgICAgICAgICBjbGFzcz1cImltcG9ydC1jc3ZcIlxuICAgICAgICAgIFthdXRvR3Jvd109XCJ0cnVlXCJcbiAgICAgICAgICBbcm93c109XCI2XCJcbiAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwidCgnY3N2UGxhY2Vob2xkZXInKVwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJjc3ZcIlxuICAgICAgICAvPlxuXG4gICAgICAgIDxpb24tc2VsZWN0XG4gICAgICAgICAgY2xhc3M9XCJpbXBvcnQtY29uZmxpY3RcIlxuICAgICAgICAgIGxhYmVsPVwie3sgdCgnb25Db25mbGljdExhYmVsJykgfX1cIlxuICAgICAgICAgIGxhYmVsUGxhY2VtZW50PVwic3RhY2tlZFwiXG4gICAgICAgICAgaW50ZXJmYWNlPVwicG9wb3ZlclwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJvbkNvbmZsaWN0XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cImFzc2lnblJvbGVcIj57eyB0KCdjb25mbGljdEFzc2lnbicpIH19PC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gdmFsdWU9XCJza2lwXCI+e3sgdCgnY29uZmxpY3RTa2lwJykgfX08L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cImVycm9yXCI+e3sgdCgnY29uZmxpY3RFcnJvcicpIH19PC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgPC9pb24tc2VsZWN0PlxuXG4gICAgICAgIDxpb24tY2hlY2tib3ggY2xhc3M9XCJpbXBvcnQtYWN0aXZhdGlvblwiIGxhYmVsUGxhY2VtZW50PVwiZW5kXCIgWyhuZ01vZGVsKV09XCJzZW5kQWN0aXZhdGlvblwiPlxuICAgICAgICAgIHt7IHQoJ3NlbmRBY3RpdmF0aW9uJykgfX1cbiAgICAgICAgPC9pb24tY2hlY2tib3g+XG5cbiAgICAgICAgQGlmIChlcnJvck1zZygpKSB7XG4gICAgICAgICAgPHAgY2xhc3M9XCJpbXBvcnQtZXJyb3JcIj57eyBlcnJvck1zZygpIH19PC9wPlxuICAgICAgICB9XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImltcG9ydC1hY3Rpb25zXCI+XG4gICAgICAgICAgPGlvbi1idXR0b24gZXhwYW5kPVwiYmxvY2tcIiBjb2xvcj1cImRhcmtcIiBbZGlzYWJsZWRdPVwic3VibWl0dGluZygpXCIgKGNsaWNrKT1cInN1Ym1pdCgpXCI+XG4gICAgICAgICAgICBAaWYgKHN1Ym1pdHRpbmcoKSkge1xuICAgICAgICAgICAgICA8aW9uLXNwaW5uZXIgbmFtZT1cImRvdHNcIiAvPlxuICAgICAgICAgICAgICAmbmJzcDt7eyB0KCdzdWJtaXR0aW5nJykgfX1cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICB7eyB0KCdzdWJtaXQnKSB9fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPCEtLSBSZXN1bHRhZG9zIC0tPlxuICAgICAgICA8dmFsLXRpdGxlIFtwcm9wc109XCJ7IGNvbnRlbnQ6IHN1bW1hcnlMYWJlbCgpLCBzaXplOiAnbGFyZ2UnLCBjb2xvcjogJycsIGJvbGQ6IHRydWUgfVwiIC8+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbXBvcnQtcmVzdWx0c1wiPlxuICAgICAgICAgIEBmb3IgKHIgb2YgcmVzdWx0cygpIS5yZXN1bHRzOyB0cmFjayByLmVtYWlsKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW1wb3J0LXJvdyBpbXBvcnQtcm93LS17eyByLnN0YXR1cyB9fVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImltcG9ydC1yb3dfX2VtYWlsXCI+e3sgci5lbWFpbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbXBvcnQtcm93X19zdGF0dXNcIj57eyBzdGF0dXNMYWJlbChyKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgQGlmIChyLnJlYXNvbikge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW1wb3J0LXJvd19fcmVhc29uXCI+e3sgci5yZWFzb24gfX08L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbXBvcnQtYWN0aW9uc1wiPlxuICAgICAgICAgIDxpb24tYnV0dG9uIGV4cGFuZD1cImJsb2NrXCIgZmlsbD1cIm91dGxpbmVcIiBjb2xvcj1cImRhcmtcIiAoY2xpY2spPVwicmVzZXQoKVwiPlxuICAgICAgICAgICAge3sgdCgnYWdhaW4nKSB9fVxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9pb24tY29udGVudD5cbiAgYCxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgdmFsLWRpc3BsYXkge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogNHB4O1xuICAgICAgfVxuICAgICAgdmFsLXRpdGxlIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDEycHg7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LWNzdiB7XG4gICAgICAgIC0tYmFja2dyb3VuZDogdmFyKC0taW9uLWNvbG9yLWxpZ2h0KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMTZweDtcbiAgICAgICAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcbiAgICAgICAgZm9udC1zaXplOiAxM3B4O1xuICAgICAgfVxuICAgICAgLmltcG9ydC1jb25mbGljdCB7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDEycHg7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LWFjdGl2YXRpb24ge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMTZweDtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgfVxuICAgICAgLmltcG9ydC1lcnJvciB7XG4gICAgICAgIG1hcmdpbjogMCAwIDEycHggMDtcbiAgICAgICAgZm9udC1zaXplOiAwLjg3NXJlbTtcbiAgICAgICAgY29sb3I6IHZhcigtLWlvbi1jb2xvci1kYW5nZXIsICNjMDM5MmIpO1xuICAgICAgfVxuICAgICAgLmltcG9ydC1hY3Rpb25zIHtcbiAgICAgICAgbWFyZ2luLXRvcDogOHB4O1xuICAgICAgfVxuICAgICAgLmltcG9ydC1yZXN1bHRzIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgZ2FwOiA2cHg7XG4gICAgICAgIG1hcmdpbjogMTJweCAwO1xuICAgICAgfVxuICAgICAgLmltcG9ydC1yb3cge1xuICAgICAgICBkaXNwbGF5OiBncmlkO1xuICAgICAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciBhdXRvO1xuICAgICAgICBncmlkLXJvdy1nYXA6IDJweDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgcGFkZGluZzogMTBweCAxMnB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICAgIGJvcmRlci1sZWZ0OiAzcHggc29saWQgdmFyKC0taW9uLWNvbG9yLW1lZGl1bSk7XG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWlvbi1jb2xvci1saWdodCk7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93LS1jcmVhdGVkIHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6IHZhcigtLWlvbi1jb2xvci1zdWNjZXNzLCAjMmRkMzZmKTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93LS1hc3NpZ25lZCB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiB2YXIoLS1pb24tY29sb3ItcHJpbWFyeSwgIzcwMjZkZik7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LXJvdy0tc2tpcHBlZCB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiB2YXIoLS1pb24tY29sb3ItbWVkaXVtLCAjOTI5NDljKTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93LS1lcnJvciB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiB2YXIoLS1pb24tY29sb3ItZGFuZ2VyLCAjYzAzOTJiKTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93X19lbWFpbCB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1pb24tY29sb3ItZGFyayk7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LXJvd19fc3RhdHVzIHtcbiAgICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1pb24tY29sb3ItbWVkaXVtLXNoYWRlLCAjNmI2ZTc2KTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93X19yZWFzb24ge1xuICAgICAgICBncmlkLWNvbHVtbjogMSAvIC0xO1xuICAgICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1pb24tY29sb3ItZGFuZ2VyLCAjYzAzOTJiKTtcbiAgICAgIH1cbiAgICBgLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBNZW1iZXJJbXBvcnRNb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgaTE4biA9IGluamVjdChJMThuU2VydmljZSk7XG4gIHByaXZhdGUgb3JnU2VydmljZSA9IGluamVjdChPcmdTZXJ2aWNlKTtcblxuICAvKiogT3JnIGRlc3Rpbm8gZGVsIGltcG9ydC4gKi9cbiAgQElucHV0KCkgb3JnSWQgPSAnJztcblxuICAvKiogTm9tYnJlcyBkZSByb2xlcyBkaXNwb25pYmxlcyAocGFyYSBlbCBoaW50KS4gT3BjaW9uYWwuICovXG4gIEBJbnB1dCgpIGF2YWlsYWJsZVJvbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8qKiBDYWxsYmFjayB0cmFzIHVuYSBpbXBvcnRhY2nDs24gZXhpdG9zYSAo4omlMSBmaWxhIHByb2Nlc2FkYSkg4oCUIHJlZnJlc2NhIGxhIGxpc3RhLiAqL1xuICBASW5wdXQoKSBvblN1Y2Nlc3M/OiAoKSA9PiB2b2lkO1xuXG4gIC8qKiBJbnllY3RhZG8gcG9yIGBNb2RhbFNlcnZpY2Uub3BlbmAuICovXG4gIEBJbnB1dCgpIF9tb2RhbFJlZj86IHsgZGlzbWlzczogKGRhdGE/OiB1bmtub3duLCByb2xlPzogc3RyaW5nKSA9PiB2b2lkIH07XG5cbiAgLyoqIE5hbWVzcGFjZSBpMThuLiAqL1xuICBASW5wdXQoKSBpMThuTmFtZXNwYWNlID0gREVGQVVMVF9OQU1FU1BBQ0U7XG5cbiAgY3N2ID0gJyc7XG4gIG9uQ29uZmxpY3Q6IEltcG9ydE9uQ29uZmxpY3QgPSAnYXNzaWduUm9sZSc7XG4gIHNlbmRBY3RpdmF0aW9uID0gdHJ1ZTtcblxuICByZWFkb25seSBzdWJtaXR0aW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgZXJyb3JNc2cgPSBzaWduYWwoJycpO1xuICByZWFkb25seSByZXN1bHRzID0gc2lnbmFsPEltcG9ydE1lbWJlcnNSZXNwb25zZSB8IG51bGw+KG51bGwpO1xuXG4gIHJlYWRvbmx5IHJvbGVzSGludCA9IGNvbXB1dGVkKCgpID0+XG4gICAgdGhpcy5hdmFpbGFibGVSb2xlcy5sZW5ndGggPyBgJHt0aGlzLnQoJ3JvbGVzQXZhaWxhYmxlJyl9ICR7dGhpcy5hdmFpbGFibGVSb2xlcy5qb2luKCcsICcpfWAgOiAnJ1xuICApO1xuXG4gIHJlYWRvbmx5IHN1bW1hcnlMYWJlbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBzID0gdGhpcy5yZXN1bHRzKCk/LnN1bW1hcnk7XG4gICAgaWYgKCFzKSByZXR1cm4gdGhpcy50KCdzdW1tYXJ5Jyk7XG4gICAgcmV0dXJuIGAke3RoaXMudCgnc3VtbWFyeScpfTogJHtzLmNyZWF0ZWR9ICR7dGhpcy50KCdjcmVhdGVkJyl9IMK3ICR7cy5hc3NpZ25lZH0gJHt0aGlzLnQoXG4gICAgICAnYXNzaWduZWQnXG4gICAgKX0gwrcgJHtzLnNraXBwZWR9ICR7dGhpcy50KCdza2lwcGVkJyl9IMK3ICR7cy5mYWlsZWR9ICR7dGhpcy50KCdmYWlsZWQnKX1gO1xuICB9KTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAoIXRoaXMuaTE4bi5oYXNOYW1lc3BhY2UoREVGQVVMVF9OQU1FU1BBQ0UpKSB7XG4gICAgICB0aGlzLmkxOG4ucmVnaXN0ZXJDb250ZW50KERFRkFVTFRfTkFNRVNQQUNFLCBNRU1CRVJfSU1QT1JUX01PREFMX0kxOE4pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pMThuLmhhc05hbWVzcGFjZSh0aGlzLmkxOG5OYW1lc3BhY2UpKSB7XG4gICAgICB0aGlzLmkxOG4ucmVnaXN0ZXJDb250ZW50KHRoaXMuaTE4bk5hbWVzcGFjZSwgTUVNQkVSX0lNUE9SVF9NT0RBTF9JMThOKTtcbiAgICB9XG4gIH1cblxuICAvKiogUGFyc2VhIGVsIENTViBwZWdhZG8gYSBmaWxhcyB7ZW1haWwsbmFtZSxyb2xlTmFtZX0uIFRvbGVyYSBoZWFkZXIuICovXG4gIHByaXZhdGUgcGFyc2VDc3YoKTogSW1wb3J0VXNlclJvd1tdIHtcbiAgICBjb25zdCByb3dzOiBJbXBvcnRVc2VyUm93W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHJhdyBvZiB0aGlzLmNzdi5zcGxpdCgvXFxyP1xcbi8pKSB7XG4gICAgICBjb25zdCBsaW5lID0gcmF3LnRyaW0oKTtcbiAgICAgIGlmICghbGluZSkgY29udGludWU7XG4gICAgICBjb25zdCBjb2xzID0gbGluZS5zcGxpdCgnLCcpLm1hcChjID0+IGMudHJpbSgpKTtcbiAgICAgIGNvbnN0IGVtYWlsID0gKGNvbHNbMF0gPz8gJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAvLyBTYWx0YXIgaGVhZGVyIChwcmltZXJhIGNvbCBcImVtYWlsXCIpIG8gbMOtbmVhcyBzaW4gQC5cbiAgICAgIGlmICghZW1haWwgfHwgIWVtYWlsLmluY2x1ZGVzKCdAJykpIGNvbnRpbnVlO1xuICAgICAgcm93cy5wdXNoKHsgZW1haWwsIG5hbWU6IGNvbHNbMV0gPz8gJycsIHJvbGVOYW1lOiBjb2xzWzJdID8/ICcnIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIHN1Ym1pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVycm9yTXNnLnNldCgnJyk7XG4gICAgY29uc3QgdXNlcnMgPSB0aGlzLnBhcnNlQ3N2KCk7XG4gICAgaWYgKHVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZy5zZXQodGhpcy50KCdub1Jvd3MnKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh1c2Vycy5zb21lKHUgPT4gIXUucm9sZU5hbWUpKSB7XG4gICAgICB0aGlzLmVycm9yTXNnLnNldCh0aGlzLnQoJ3BhcnNlRXJyb3InKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdWJtaXR0aW5nLnNldCh0cnVlKTtcbiAgICB0aGlzLm9yZ1NlcnZpY2VcbiAgICAgIC5pbXBvcnRNZW1iZXJzKHRoaXMub3JnSWQsIHtcbiAgICAgICAgdXNlcnMsXG4gICAgICAgIG9uQ29uZmxpY3Q6IHRoaXMub25Db25mbGljdCxcbiAgICAgICAgc2VuZEFjdGl2YXRpb246IHRoaXMuc2VuZEFjdGl2YXRpb24sXG4gICAgICB9KVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IHJlcyA9PiB7XG4gICAgICAgICAgdGhpcy5zdWJtaXR0aW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5yZXN1bHRzLnNldChyZXMpO1xuICAgICAgICAgIC8vIFJlZnJlc2NhciBsaXN0YSBkZWwgY29uc3VtZXIgc2kgaHVibyBhbHRhcy9hc2lnbmFjaW9uZXMgZWZlY3RpdmFzLlxuICAgICAgICAgIGlmIChyZXMuc3VtbWFyeS5jcmVhdGVkICsgcmVzLnN1bW1hcnkuYXNzaWduZWQgPiAwKSB7XG4gICAgICAgICAgICB0aGlzLm9uU3VjY2Vzcz8uKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICB0aGlzLnN1Ym1pdHRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICB0aGlzLmVycm9yTXNnLnNldChlcnI/LmVycm9yPy5tZXNzYWdlID8/IHRoaXMudCgnZ2VuZXJpY0Vycm9yJykpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gIH1cblxuICBzdGF0dXNMYWJlbChyOiBJbXBvcnRSb3dSZXN1bHQpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJhc2UgPSB0aGlzLnQoci5zdGF0dXMgPT09ICdlcnJvcicgPyAnZmFpbGVkJyA6IHIuc3RhdHVzKTtcbiAgICBpZiAoci5zdGF0dXMgPT09ICdjcmVhdGVkJyAmJiByLmFjdGl2YXRpb24pIHtcbiAgICAgIHJldHVybiBgJHtiYXNlfSDCtyAke3RoaXMudChyLmFjdGl2YXRpb24gPT09ICdzZW50JyA/ICdhY3RpdmF0aW9uU2VudCcgOiAnYWN0aXZhdGlvblBlbmRpbmcnKX1gO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZTtcbiAgfVxuXG4gIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuY3N2ID0gJyc7XG4gICAgdGhpcy5lcnJvck1zZy5zZXQoJycpO1xuICAgIHRoaXMucmVzdWx0cy5zZXQobnVsbCk7XG4gIH1cblxuICBkaXNtaXNzKCk6IHZvaWQge1xuICAgIHRoaXMuX21vZGFsUmVmPy5kaXNtaXNzKG51bGwsICdjYW5jZWwnKTtcbiAgfVxuXG4gIHQoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmkxOG4udChrZXksIHRoaXMuaTE4bk5hbWVzcGFjZSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,63 +0,0 @@
1
- /**
2
- * Defaults i18n (es/en) embebidos en `val-member-import-modal` (ADR-023).
3
- * Auto-registrados si el consumer no proveyó el namespace `Settings.ImportModal`.
4
- */
5
- export const MEMBER_IMPORT_MODAL_I18N = {
6
- es: {
7
- title: 'Importar miembros',
8
- hint: 'Pega un CSV con columnas: email, nombre, rol (una fila por persona).',
9
- csvPlaceholder: 'email,nombre,rol\nana@x.com,Ana,editor\nbeto@x.com,Beto,viewer',
10
- rolesAvailable: 'Roles disponibles:',
11
- onConflictLabel: 'Si el email ya existe',
12
- conflictAssign: 'Asignar el rol',
13
- conflictSkip: 'Omitir',
14
- conflictError: 'Marcar error',
15
- sendActivation: 'Enviar email de activación a las cuentas nuevas',
16
- submit: 'Importar',
17
- submitting: 'Importando...',
18
- parseError: 'No se pudo interpretar el CSV. Revisa el formato.',
19
- noRows: 'Pega al menos una fila válida (email y rol).',
20
- summary: 'Resumen',
21
- created: 'creados',
22
- assigned: 'asignados',
23
- skipped: 'omitidos',
24
- failed: 'con error',
25
- colEmail: 'Email',
26
- colStatus: 'Estado',
27
- colDetail: 'Detalle',
28
- activationSent: 'activación enviada',
29
- activationPending: 'activación pendiente',
30
- again: 'Importar otro lote',
31
- close: 'Cerrar',
32
- genericError: 'No se pudo completar la importación. Intenta de nuevo.',
33
- },
34
- en: {
35
- title: 'Import members',
36
- hint: 'Paste a CSV with columns: email, name, role (one row per person).',
37
- csvPlaceholder: 'email,name,role\nana@x.com,Ana,editor\nbeto@x.com,Beto,viewer',
38
- rolesAvailable: 'Available roles:',
39
- onConflictLabel: 'If the email already exists',
40
- conflictAssign: 'Assign the role',
41
- conflictSkip: 'Skip',
42
- conflictError: 'Mark as error',
43
- sendActivation: 'Send activation email to new accounts',
44
- submit: 'Import',
45
- submitting: 'Importing...',
46
- parseError: "Couldn't parse the CSV. Check the format.",
47
- noRows: 'Paste at least one valid row (email and role).',
48
- summary: 'Summary',
49
- created: 'created',
50
- assigned: 'assigned',
51
- skipped: 'skipped',
52
- failed: 'failed',
53
- colEmail: 'Email',
54
- colStatus: 'Status',
55
- colDetail: 'Detail',
56
- activationSent: 'activation sent',
57
- activationPending: 'activation pending',
58
- again: 'Import another batch',
59
- close: 'Close',
60
- genericError: "Couldn't complete the import. Try again.",
61
- },
62
- };
63
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLWltcG9ydC1tb2RhbC5pMThuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL29yZ2FuaXNtcy9tZW1iZXItaW1wb3J0LW1vZGFsL21lbWJlci1pbXBvcnQtbW9kYWwuaTE4bi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBcUI7SUFDeEQsRUFBRSxFQUFFO1FBQ0YsS0FBSyxFQUFFLG1CQUFtQjtRQUMxQixJQUFJLEVBQUUsc0VBQXNFO1FBQzVFLGNBQWMsRUFBRSxnRUFBZ0U7UUFDaEYsY0FBYyxFQUFFLG9CQUFvQjtRQUNwQyxlQUFlLEVBQUUsdUJBQXVCO1FBQ3hDLGNBQWMsRUFBRSxnQkFBZ0I7UUFDaEMsWUFBWSxFQUFFLFFBQVE7UUFDdEIsYUFBYSxFQUFFLGNBQWM7UUFDN0IsY0FBYyxFQUFFLGlEQUFpRDtRQUNqRSxNQUFNLEVBQUUsVUFBVTtRQUNsQixVQUFVLEVBQUUsZUFBZTtRQUMzQixVQUFVLEVBQUUsbURBQW1EO1FBQy9ELE1BQU0sRUFBRSw4Q0FBOEM7UUFDdEQsT0FBTyxFQUFFLFNBQVM7UUFDbEIsT0FBTyxFQUFFLFNBQVM7UUFDbEIsUUFBUSxFQUFFLFdBQVc7UUFDckIsT0FBTyxFQUFFLFVBQVU7UUFDbkIsTUFBTSxFQUFFLFdBQVc7UUFDbkIsUUFBUSxFQUFFLE9BQU87UUFDakIsU0FBUyxFQUFFLFFBQVE7UUFDbkIsU0FBUyxFQUFFLFNBQVM7UUFDcEIsY0FBYyxFQUFFLG9CQUFvQjtRQUNwQyxpQkFBaUIsRUFBRSxzQkFBc0I7UUFDekMsS0FBSyxFQUFFLG9CQUFvQjtRQUMzQixLQUFLLEVBQUUsUUFBUTtRQUNmLFlBQVksRUFBRSx3REFBd0Q7S0FDdkU7SUFDRCxFQUFFLEVBQUU7UUFDRixLQUFLLEVBQUUsZ0JBQWdCO1FBQ3ZCLElBQUksRUFBRSxtRUFBbUU7UUFDekUsY0FBYyxFQUFFLCtEQUErRDtRQUMvRSxjQUFjLEVBQUUsa0JBQWtCO1FBQ2xDLGVBQWUsRUFBRSw2QkFBNkI7UUFDOUMsY0FBYyxFQUFFLGlCQUFpQjtRQUNqQyxZQUFZLEVBQUUsTUFBTTtRQUNwQixhQUFhLEVBQUUsZUFBZTtRQUM5QixjQUFjLEVBQUUsdUNBQXVDO1FBQ3ZELE1BQU0sRUFBRSxRQUFRO1FBQ2hCLFVBQVUsRUFBRSxjQUFjO1FBQzFCLFVBQVUsRUFBRSwyQ0FBMkM7UUFDdkQsTUFBTSxFQUFFLGdEQUFnRDtRQUN4RCxPQUFPLEVBQUUsU0FBUztRQUNsQixPQUFPLEVBQUUsU0FBUztRQUNsQixRQUFRLEVBQUUsVUFBVTtRQUNwQixPQUFPLEVBQUUsU0FBUztRQUNsQixNQUFNLEVBQUUsUUFBUTtRQUNoQixRQUFRLEVBQUUsT0FBTztRQUNqQixTQUFTLEVBQUUsUUFBUTtRQUNuQixTQUFTLEVBQUUsUUFBUTtRQUNuQixjQUFjLEVBQUUsaUJBQWlCO1FBQ2pDLGlCQUFpQixFQUFFLG9CQUFvQjtRQUN2QyxLQUFLLEVBQUUsc0JBQXNCO1FBQzdCLEtBQUssRUFBRSxPQUFPO1FBQ2QsWUFBWSxFQUFFLDBDQUEwQztLQUN6RDtDQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMYW5ndWFnZXNDb250ZW50IH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvaTE4bi90eXBlcyc7XG5cbi8qKlxuICogRGVmYXVsdHMgaTE4biAoZXMvZW4pIGVtYmViaWRvcyBlbiBgdmFsLW1lbWJlci1pbXBvcnQtbW9kYWxgIChBRFItMDIzKS5cbiAqIEF1dG8tcmVnaXN0cmFkb3Mgc2kgZWwgY29uc3VtZXIgbm8gcHJvdmV5w7MgZWwgbmFtZXNwYWNlIGBTZXR0aW5ncy5JbXBvcnRNb2RhbGAuXG4gKi9cbmV4cG9ydCBjb25zdCBNRU1CRVJfSU1QT1JUX01PREFMX0kxOE46IExhbmd1YWdlc0NvbnRlbnQgPSB7XG4gIGVzOiB7XG4gICAgdGl0bGU6ICdJbXBvcnRhciBtaWVtYnJvcycsXG4gICAgaGludDogJ1BlZ2EgdW4gQ1NWIGNvbiBjb2x1bW5hczogZW1haWwsIG5vbWJyZSwgcm9sICh1bmEgZmlsYSBwb3IgcGVyc29uYSkuJyxcbiAgICBjc3ZQbGFjZWhvbGRlcjogJ2VtYWlsLG5vbWJyZSxyb2xcXG5hbmFAeC5jb20sQW5hLGVkaXRvclxcbmJldG9AeC5jb20sQmV0byx2aWV3ZXInLFxuICAgIHJvbGVzQXZhaWxhYmxlOiAnUm9sZXMgZGlzcG9uaWJsZXM6JyxcbiAgICBvbkNvbmZsaWN0TGFiZWw6ICdTaSBlbCBlbWFpbCB5YSBleGlzdGUnLFxuICAgIGNvbmZsaWN0QXNzaWduOiAnQXNpZ25hciBlbCByb2wnLFxuICAgIGNvbmZsaWN0U2tpcDogJ09taXRpcicsXG4gICAgY29uZmxpY3RFcnJvcjogJ01hcmNhciBlcnJvcicsXG4gICAgc2VuZEFjdGl2YXRpb246ICdFbnZpYXIgZW1haWwgZGUgYWN0aXZhY2nDs24gYSBsYXMgY3VlbnRhcyBudWV2YXMnLFxuICAgIHN1Ym1pdDogJ0ltcG9ydGFyJyxcbiAgICBzdWJtaXR0aW5nOiAnSW1wb3J0YW5kby4uLicsXG4gICAgcGFyc2VFcnJvcjogJ05vIHNlIHB1ZG8gaW50ZXJwcmV0YXIgZWwgQ1NWLiBSZXZpc2EgZWwgZm9ybWF0by4nLFxuICAgIG5vUm93czogJ1BlZ2EgYWwgbWVub3MgdW5hIGZpbGEgdsOhbGlkYSAoZW1haWwgeSByb2wpLicsXG4gICAgc3VtbWFyeTogJ1Jlc3VtZW4nLFxuICAgIGNyZWF0ZWQ6ICdjcmVhZG9zJyxcbiAgICBhc3NpZ25lZDogJ2FzaWduYWRvcycsXG4gICAgc2tpcHBlZDogJ29taXRpZG9zJyxcbiAgICBmYWlsZWQ6ICdjb24gZXJyb3InLFxuICAgIGNvbEVtYWlsOiAnRW1haWwnLFxuICAgIGNvbFN0YXR1czogJ0VzdGFkbycsXG4gICAgY29sRGV0YWlsOiAnRGV0YWxsZScsXG4gICAgYWN0aXZhdGlvblNlbnQ6ICdhY3RpdmFjacOzbiBlbnZpYWRhJyxcbiAgICBhY3RpdmF0aW9uUGVuZGluZzogJ2FjdGl2YWNpw7NuIHBlbmRpZW50ZScsXG4gICAgYWdhaW46ICdJbXBvcnRhciBvdHJvIGxvdGUnLFxuICAgIGNsb3NlOiAnQ2VycmFyJyxcbiAgICBnZW5lcmljRXJyb3I6ICdObyBzZSBwdWRvIGNvbXBsZXRhciBsYSBpbXBvcnRhY2nDs24uIEludGVudGEgZGUgbnVldm8uJyxcbiAgfSxcbiAgZW46IHtcbiAgICB0aXRsZTogJ0ltcG9ydCBtZW1iZXJzJyxcbiAgICBoaW50OiAnUGFzdGUgYSBDU1Ygd2l0aCBjb2x1bW5zOiBlbWFpbCwgbmFtZSwgcm9sZSAob25lIHJvdyBwZXIgcGVyc29uKS4nLFxuICAgIGNzdlBsYWNlaG9sZGVyOiAnZW1haWwsbmFtZSxyb2xlXFxuYW5hQHguY29tLEFuYSxlZGl0b3JcXG5iZXRvQHguY29tLEJldG8sdmlld2VyJyxcbiAgICByb2xlc0F2YWlsYWJsZTogJ0F2YWlsYWJsZSByb2xlczonLFxuICAgIG9uQ29uZmxpY3RMYWJlbDogJ0lmIHRoZSBlbWFpbCBhbHJlYWR5IGV4aXN0cycsXG4gICAgY29uZmxpY3RBc3NpZ246ICdBc3NpZ24gdGhlIHJvbGUnLFxuICAgIGNvbmZsaWN0U2tpcDogJ1NraXAnLFxuICAgIGNvbmZsaWN0RXJyb3I6ICdNYXJrIGFzIGVycm9yJyxcbiAgICBzZW5kQWN0aXZhdGlvbjogJ1NlbmQgYWN0aXZhdGlvbiBlbWFpbCB0byBuZXcgYWNjb3VudHMnLFxuICAgIHN1Ym1pdDogJ0ltcG9ydCcsXG4gICAgc3VibWl0dGluZzogJ0ltcG9ydGluZy4uLicsXG4gICAgcGFyc2VFcnJvcjogXCJDb3VsZG4ndCBwYXJzZSB0aGUgQ1NWLiBDaGVjayB0aGUgZm9ybWF0LlwiLFxuICAgIG5vUm93czogJ1Bhc3RlIGF0IGxlYXN0IG9uZSB2YWxpZCByb3cgKGVtYWlsIGFuZCByb2xlKS4nLFxuICAgIHN1bW1hcnk6ICdTdW1tYXJ5JyxcbiAgICBjcmVhdGVkOiAnY3JlYXRlZCcsXG4gICAgYXNzaWduZWQ6ICdhc3NpZ25lZCcsXG4gICAgc2tpcHBlZDogJ3NraXBwZWQnLFxuICAgIGZhaWxlZDogJ2ZhaWxlZCcsXG4gICAgY29sRW1haWw6ICdFbWFpbCcsXG4gICAgY29sU3RhdHVzOiAnU3RhdHVzJyxcbiAgICBjb2xEZXRhaWw6ICdEZXRhaWwnLFxuICAgIGFjdGl2YXRpb25TZW50OiAnYWN0aXZhdGlvbiBzZW50JyxcbiAgICBhY3RpdmF0aW9uUGVuZGluZzogJ2FjdGl2YXRpb24gcGVuZGluZycsXG4gICAgYWdhaW46ICdJbXBvcnQgYW5vdGhlciBiYXRjaCcsXG4gICAgY2xvc2U6ICdDbG9zZScsXG4gICAgZ2VuZXJpY0Vycm9yOiBcIkNvdWxkbid0IGNvbXBsZXRlIHRoZSBpbXBvcnQuIFRyeSBhZ2Fpbi5cIixcbiAgfSxcbn07XG4iXX0=
@@ -1,46 +0,0 @@
1
- import { Injectable, Inject } from '@angular/core';
2
- import { map } from 'rxjs/operators';
3
- import { VALTECH_AUTH_CONFIG } from '../auth/config';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "@angular/common/http";
6
- /**
7
- * Cliente HTTP de Client API Keys org-scopeadas (ADR-023). La org activa se
8
- * resuelve en backend desde el JWT, así que el path no la incluye.
9
- */
10
- export class ApiKeyService {
11
- constructor(config, http) {
12
- this.config = config;
13
- this.http = http;
14
- }
15
- get baseUrl() {
16
- return `${this.config.apiUrl}/org/api-keys`;
17
- }
18
- /** Lista las API keys de la org activa. */
19
- list() {
20
- return this.http.get(`${this.baseUrl}/`).pipe(map(r => r.keys ?? []));
21
- }
22
- /** Crea una API key. La respuesta incluye el secreto (se muestra UNA vez). */
23
- create(req) {
24
- return this.http.post(`${this.baseUrl}/`, req);
25
- }
26
- /** Revoca (elimina) una API key por id. */
27
- revoke(keyId) {
28
- return this.http.delete(`${this.baseUrl}/${keyId}`);
29
- }
30
- /** Catálogo de permisos asignables a una key. */
31
- availablePermissions() {
32
- return this.http
33
- .get(`${this.baseUrl}/permissions`)
34
- .pipe(map(r => r.permissions ?? []));
35
- }
36
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ApiKeyService, deps: [{ token: VALTECH_AUTH_CONFIG }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
37
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ApiKeyService, providedIn: 'root' }); }
38
- }
39
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ApiKeyService, decorators: [{
40
- type: Injectable,
41
- args: [{ providedIn: 'root' }]
42
- }], ctorParameters: () => [{ type: undefined, decorators: [{
43
- type: Inject,
44
- args: [VALTECH_AUTH_CONFIG]
45
- }] }, { type: i1.HttpClient }] });
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWtleXMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc2VydmljZXMvYXBpa2V5cy9hcGkta2V5cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR25ELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBV3JEOzs7R0FHRztBQUVILE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQ3VDLE1BQXlCLEVBQ3RELElBQWdCO1FBRGEsV0FBTSxHQUFOLE1BQU0sQ0FBbUI7UUFDdEQsU0FBSSxHQUFKLElBQUksQ0FBWTtJQUN2QixDQUFDO0lBRUosSUFBWSxPQUFPO1FBQ2pCLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sZUFBZSxDQUFDO0lBQzlDLENBQUM7SUFFRCwyQ0FBMkM7SUFDM0MsSUFBSTtRQUNGLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQXNCLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM3RixDQUFDO0lBRUQsOEVBQThFO0lBQzlFLE1BQU0sQ0FBQyxHQUF3QjtRQUM3QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUF1QixHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsMkNBQTJDO0lBQzNDLE1BQU0sQ0FBQyxLQUFhO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQXVCLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFRCxpREFBaUQ7SUFDakQsb0JBQW9CO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLElBQUk7YUFDYixHQUFHLENBQStCLEdBQUcsSUFBSSxDQUFDLE9BQU8sY0FBYyxDQUFDO2FBQ2hFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekMsQ0FBQzsrR0E5QlUsYUFBYSxrQkFFZCxtQkFBbUI7bUhBRmxCLGFBQWEsY0FEQSxNQUFNOzs0RkFDbkIsYUFBYTtrQkFEekIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7OzBCQUc3QixNQUFNOzJCQUFDLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgVkFMVEVDSF9BVVRIX0NPTkZJRyB9IGZyb20gJy4uL2F1dGgvY29uZmlnJztcbmltcG9ydCB7IFZhbHRlY2hBdXRoQ29uZmlnIH0gZnJvbSAnLi4vYXV0aC90eXBlcyc7XG5pbXBvcnQge1xuICBBdmFpbGFibGVQZXJtaXNzaW9uc1Jlc3BvbnNlLFxuICBDbGllbnRBcGlLZXksXG4gIENyZWF0ZUFwaUtleVJlcXVlc3QsXG4gIENyZWF0ZUFwaUtleVJlc3BvbnNlLFxuICBMaXN0QXBpS2V5c1Jlc3BvbnNlLFxuICBSZXZva2VBcGlLZXlSZXNwb25zZSxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogQ2xpZW50ZSBIVFRQIGRlIENsaWVudCBBUEkgS2V5cyBvcmctc2NvcGVhZGFzIChBRFItMDIzKS4gTGEgb3JnIGFjdGl2YSBzZVxuICogcmVzdWVsdmUgZW4gYmFja2VuZCBkZXNkZSBlbCBKV1QsIGFzw60gcXVlIGVsIHBhdGggbm8gbGEgaW5jbHV5ZS5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBBcGlLZXlTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWQUxURUNIX0FVVEhfQ09ORklHKSBwcml2YXRlIGNvbmZpZzogVmFsdGVjaEF1dGhDb25maWcsXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50XG4gICkge31cblxuICBwcml2YXRlIGdldCBiYXNlVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmFwaVVybH0vb3JnL2FwaS1rZXlzYDtcbiAgfVxuXG4gIC8qKiBMaXN0YSBsYXMgQVBJIGtleXMgZGUgbGEgb3JnIGFjdGl2YS4gKi9cbiAgbGlzdCgpOiBPYnNlcnZhYmxlPENsaWVudEFwaUtleVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8TGlzdEFwaUtleXNSZXNwb25zZT4oYCR7dGhpcy5iYXNlVXJsfS9gKS5waXBlKG1hcChyID0+IHIua2V5cyA/PyBbXSkpO1xuICB9XG5cbiAgLyoqIENyZWEgdW5hIEFQSSBrZXkuIExhIHJlc3B1ZXN0YSBpbmNsdXllIGVsIHNlY3JldG8gKHNlIG11ZXN0cmEgVU5BIHZleikuICovXG4gIGNyZWF0ZShyZXE6IENyZWF0ZUFwaUtleVJlcXVlc3QpOiBPYnNlcnZhYmxlPENyZWF0ZUFwaUtleVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PENyZWF0ZUFwaUtleVJlc3BvbnNlPihgJHt0aGlzLmJhc2VVcmx9L2AsIHJlcSk7XG4gIH1cblxuICAvKiogUmV2b2NhIChlbGltaW5hKSB1bmEgQVBJIGtleSBwb3IgaWQuICovXG4gIHJldm9rZShrZXlJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxSZXZva2VBcGlLZXlSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlPFJldm9rZUFwaUtleVJlc3BvbnNlPihgJHt0aGlzLmJhc2VVcmx9LyR7a2V5SWR9YCk7XG4gIH1cblxuICAvKiogQ2F0w6Fsb2dvIGRlIHBlcm1pc29zIGFzaWduYWJsZXMgYSB1bmEga2V5LiAqL1xuICBhdmFpbGFibGVQZXJtaXNzaW9ucygpOiBPYnNlcnZhYmxlPHN0cmluZ1tdPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cFxuICAgICAgLmdldDxBdmFpbGFibGVQZXJtaXNzaW9uc1Jlc3BvbnNlPihgJHt0aGlzLmJhc2VVcmx9L3Blcm1pc3Npb25zYClcbiAgICAgIC5waXBlKG1hcChyID0+IHIucGVybWlzc2lvbnMgPz8gW10pKTtcbiAgfVxufVxuIl19
@@ -1,7 +0,0 @@
1
- /**
2
- * Tipos de Client API Keys org-scopeadas (ADR-023). Contrato espejo de
3
- * `lambdas/org` `/org/api-keys/*`. El orgID se resuelve del JWT (ActiveOrgID),
4
- * no va en el path.
5
- */
6
- export {};
7
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FwaWtleXMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGlwb3MgZGUgQ2xpZW50IEFQSSBLZXlzIG9yZy1zY29wZWFkYXMgKEFEUi0wMjMpLiBDb250cmF0byBlc3Blam8gZGVcbiAqIGBsYW1iZGFzL29yZ2AgYC9vcmcvYXBpLWtleXMvKmAuIEVsIG9yZ0lEIHNlIHJlc3VlbHZlIGRlbCBKV1QgKEFjdGl2ZU9yZ0lEKSxcbiAqIG5vIHZhIGVuIGVsIHBhdGguXG4gKi9cblxuZXhwb3J0IGludGVyZmFjZSBDbGllbnRBcGlLZXkge1xuICBrZXlJZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIG9yZ2FuaXphdGlvbklkOiBzdHJpbmc7XG4gIHN0YXR1czogc3RyaW5nO1xuICBwZXJtaXNzaW9uczogc3RyaW5nW107XG4gIHJhdGVMaW1pdD86IG51bWJlcjtcbiAgZXhwaXJlc0F0Pzogc3RyaW5nO1xuICBhbGxvd2VkSXBzPzogc3RyaW5nW107XG4gIGNyZWF0ZWRCeTogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbiAgbGFzdFVzZWRBdD86IHN0cmluZztcbn1cblxuLyoqIFNvbG8gZW4gbGEgcmVzcHVlc3RhIGRlIGNyZWFjacOzbjogZWwgc2VjcmV0byBzZSBtdWVzdHJhIFVOQSB2ZXouICovXG5leHBvcnQgaW50ZXJmYWNlIENsaWVudEFwaUtleVdpdGhTZWNyZXQgZXh0ZW5kcyBDbGllbnRBcGlLZXkge1xuICBzZWNyZXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVBcGlLZXlSZXF1ZXN0IHtcbiAgbmFtZTogc3RyaW5nO1xuICBwZXJtaXNzaW9uczogc3RyaW5nW107XG4gIHJhdGVMaW1pdD86IG51bWJlcjtcbiAgZXhwaXJlc0luRGF5cz86IG51bWJlcjtcbiAgYWxsb3dlZElwcz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUFwaUtleVJlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAga2V5OiBDbGllbnRBcGlLZXlXaXRoU2VjcmV0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpc3RBcGlLZXlzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBrZXlzOiBDbGllbnRBcGlLZXlbXTtcbiAgbmV4dFRva2VuPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF2YWlsYWJsZVBlcm1pc3Npb25zUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBwZXJtaXNzaW9uczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV2b2tlQXBpS2V5UmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59XG4iXX0=
@@ -1,88 +0,0 @@
1
- import { ActionCardMetadata } from '../../molecules/action-card/types';
2
- import { TitleMetadata } from '../../atoms/title/types';
3
- import { AboutAction, AboutViewConfig } from './types';
4
- import * as i0 from "@angular/core";
5
- /**
6
- * `val-about-view` — vista About full-feature autocontenida (organism).
7
- * Promovida desde `showcase` bajo el proceso de ADR-021. Reúne:
8
- * - **HERO** — logo + nombre de marca + tagline + pill de versión (copiable).
9
- * - **Descripción** — título + cuerpo.
10
- * - **Acciones** — action-card de rating built-in (abre `val-content-reaction`
11
- * DIRECTAMENTE vía `ModalService`, sin wrapper local — decisión CTO) + las
12
- * acciones genéricas que el consumer aporte por `config.actions`.
13
- * - **Redes** — links sociales (`config.socialLinks`); sección oculta si vacía.
14
- * - **Footer** — copyright con el año actual.
15
- *
16
- * Lo app-specific (logo, nombre, versión, redes, acciones share/faq) viaja como
17
- * DATA de config — NO como slots (ADR-021). La versión la pasa el consumer
18
- * (`config.version` = su `APP_VERSION`); la lib NO importa el `version.ts` de la
19
- * app. Si no se pasa versión, el pill se oculta.
20
- *
21
- * NO renderiza ion-content — vive dentro de val-page-wrapper. `ActivatedRoute`
22
- * se inyecta `{ optional: true }` solo para leer el route data de config.
23
- *
24
- * Auto-registra sus defaults i18n (es/en) en el constructor si el consumer no
25
- * proveyó el namespace configurado (default `Settings.About`).
26
- *
27
- * GOTCHA i18n ContentReaction: `val-content-reaction` exige su namespace
28
- * `ContentReaction` registrado donde se use (key faltante en binding + CD =
29
- * navegador congelado en dev). `ContentReactionComponent` se auto-registra ese
30
- * namespace en SU constructor, y como se abre vía `ModalService` ese constructor
31
- * corre antes de que su template binde — queda cubierto. Igual lo importamos
32
- * como dependencia explícita de esta vista para que la garantía sea local.
33
- */
34
- export declare class AboutViewComponent {
35
- private nav;
36
- private i18n;
37
- private modalService;
38
- private toast;
39
- private route;
40
- /**
41
- * Config vía @Input (object-first). Si no se pasa, se cae al route data
42
- * `aboutConfig` (poblado por `provideValtechAboutRoutes`). `resolvedConfig`
43
- * mergea con los defaults — `@Input` gana sobre route data.
44
- */
45
- config?: AboutViewConfig;
46
- readonly resolvedConfig: import("@angular/core").Signal<Required<Omit<AboutViewConfig, "onRated">> & Pick<AboutViewConfig, "onRated">>;
47
- /** Namespace i18n resuelto (capturado para llamadas no-reactivas). */
48
- private get ns();
49
- readonly brandName: import("@angular/core").Signal<string>;
50
- readonly logoSrc: import("@angular/core").Signal<string>;
51
- readonly version: import("@angular/core").Signal<string>;
52
- readonly socialLinks: import("@angular/core").Signal<{
53
- icon: string;
54
- url: string;
55
- label: string;
56
- }[]>;
57
- readonly showRating: import("@angular/core").Signal<boolean>;
58
- readonly actions: import("@angular/core").Signal<AboutAction[]>;
59
- /** Copyright del footer — año actual interpolado en `copyrightText`. */
60
- readonly copyright: import("@angular/core").Signal<string>;
61
- /** Title metadata para secciones — bold + size small. */
62
- readonly rateActionCard: import("@angular/core").Signal<ActionCardMetadata>;
63
- constructor();
64
- /** Helper i18n bound al namespace resuelto. Reactivo vía `lang()`. */
65
- protected tt(key: string): string;
66
- /** Title metadata para secciones — bold + size small. */
67
- protected sectionTitle(key: string): TitleMetadata;
68
- /** ActionCardMetadata para una acción genérica del consumer. */
69
- protected extraActionCard(action: AboutAction): ActionCardMetadata;
70
- /** Copia la versión al portapapeles + toast (color dark). */
71
- copyVersion(): Promise<void>;
72
- /** Abre una URL externa en nueva tab. `mailto:` queda en la misma tab. */
73
- openUrl(url: string): void;
74
- /**
75
- * "Calificar la app" — abre `val-content-reaction` DIRECTAMENTE como sheet
76
- * modal (sin wrapper local — decisión CTO). El componente persiste la reacción
77
- * contra el backend de feedback y muestra su propio estado de "gracias"; el
78
- * sheet se cierra arrastrando (breakpoint 0). El namespace i18n
79
- * `ContentReaction` lo auto-registra `ContentReactionComponent` en su
80
- * constructor, que corre al crear el modal — sin riesgo de key faltante.
81
- *
82
- * Sheet (bottom sheet): el contenido scrollea dentro y el botón "Enviar" queda
83
- * siempre alcanzable, también en viewports chicos.
84
- */
85
- openRating(): Promise<void>;
86
- static ɵfac: i0.ɵɵFactoryDeclaration<AboutViewComponent, never>;
87
- static ɵcmp: i0.ɵɵComponentDeclaration<AboutViewComponent, "val-about-view", never, { "config": { "alias": "config"; "required": false; }; }, {}, never, never, true, never>;
88
- }
@@ -1,14 +0,0 @@
1
- import { LanguagesContent } from '../../../services/i18n/types';
2
- /**
3
- * Defaults i18n (es/en) embebidos en `val-about-view`. Auto-registrados en el
4
- * constructor del componente si el consumer no proveyó el namespace
5
- * (`Settings.About` por default). SOLO incluye las keys que la vista usa.
6
- *
7
- * Textos portados EXACTOS del override `Settings.About` de showcase
8
- * (`frontend/showcase/src/i18n/index.ts`). Las keys de las acciones
9
- * showcase-specific (`feedback*`, `share*`, `faq*`, `donate*`) NO se incluyen:
10
- * esas acciones se modelan ahora como `actions[]` de la config (el consumer
11
- * aporta sus propios textos). `copyrightText` se incluye aquí (antes salía del
12
- * namespace `Layout`) para que la vista sea autocontenida.
13
- */
14
- export declare const ABOUT_VIEW_I18N: LanguagesContent;
@@ -1,31 +0,0 @@
1
- import { Routes } from '@angular/router';
2
- import { AboutViewConfig } from './types';
3
- /**
4
- * Helper para montar la vista About (`val-about-view`) como ruta en una app del
5
- * factory. El `config` se pasa por route `data` (`aboutConfig`) y el componente
6
- * lo lee como fallback de su `@Input() config` (el `@Input` gana).
7
- *
8
- * @example
9
- * ```ts
10
- * // settings.routes.ts
11
- * import { APP_VERSION } from '../version';
12
- *
13
- * export const settingsRoutes: Routes = [
14
- * ...provideValtechAboutRoutes({ config: { version: APP_VERSION } }), // → /app/about
15
- * { path: 'preferences', loadComponent: () => ... },
16
- * ];
17
- *
18
- * // con redes y acciones extra:
19
- * ...provideValtechAboutRoutes({
20
- * config: {
21
- * version: APP_VERSION,
22
- * socialLinks: VALTECH_SOCIAL_LINKS.map(s => ({ icon: s.icon, url: s.url, label: s.name })),
23
- * actions: [{ label: 'Compartir', icon: 'share-social-outline', onClick: () => share() }],
24
- * },
25
- * }),
26
- * ```
27
- */
28
- export declare function provideValtechAboutRoutes(opts?: {
29
- path?: string;
30
- config?: AboutViewConfig;
31
- }): Routes;