@esfaenza/extensions 12.2.13 → 13.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/esfaenza-extensions.d.ts +1 -2
  2. package/esm2020/esfaenza-extensions.mjs +5 -0
  3. package/{esm2015/lib/models/CallResult.js → esm2020/lib/models/CallResult.mjs} +0 -0
  4. package/{esm2015/lib/models/CsvHeaders.js → esm2020/lib/models/CsvHeaders.mjs} +1 -1
  5. package/{esm2015/lib/models/ExportConsts.js → esm2020/lib/models/ExportConsts.mjs} +0 -0
  6. package/{esm2015/lib/models/ExtensionsModuleConfig.js → esm2020/lib/models/ExtensionsModuleConfig.mjs} +0 -0
  7. package/{esm2015/lib/models/GenericItem.js → esm2020/lib/models/GenericItem.mjs} +0 -0
  8. package/{esm2015/lib/models/TypeCode.js → esm2020/lib/models/TypeCode.mjs} +0 -0
  9. package/{esm2015/lib/models/providers/base/BaseStorageProvider.js → esm2020/lib/models/providers/base/BaseStorageProvider.mjs} +0 -0
  10. package/esm2020/lib/models/providers/implementation/DefaultStorageProvider.mjs +79 -0
  11. package/{esm2015/lib/models/session/base/BaseSessionRetriever.js → esm2020/lib/models/session/base/BaseSessionRetriever.mjs} +0 -0
  12. package/esm2020/lib/models/session/implementation/DefaultSessionRetriever.mjs +28 -0
  13. package/esm2020/lib/modules/extensions.full.module.mjs +58 -0
  14. package/esm2020/lib/modules/extensions.module.mjs +28 -0
  15. package/esm2020/lib/services/extensions.clipboard.service.mjs +165 -0
  16. package/esm2020/lib/services/extensions.dates.service.mjs +232 -0
  17. package/{esm2015/lib/services/extensions.exports.service.js → esm2020/lib/services/extensions.exports.service.mjs} +24 -17
  18. package/esm2020/lib/services/extensions.hashing.service.mjs +309 -0
  19. package/esm2020/lib/services/extensions.messages.service.mjs +323 -0
  20. package/esm2020/lib/services/extensions.storage.service.mjs +103 -0
  21. package/esm2020/lib/services/extensions.utilities.service.mjs +188 -0
  22. package/{esm2015/lib/tokens.js → esm2020/lib/tokens.mjs} +0 -0
  23. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  24. package/fesm2015/{esfaenza-extensions.js → esfaenza-extensions.mjs} +120 -75
  25. package/fesm2015/esfaenza-extensions.mjs.map +1 -0
  26. package/fesm2020/esfaenza-extensions.mjs +2055 -0
  27. package/fesm2020/esfaenza-extensions.mjs.map +1 -0
  28. package/lib/models/CsvHeaders.d.ts +4 -0
  29. package/lib/models/providers/implementation/DefaultStorageProvider.d.ts +3 -0
  30. package/lib/models/session/implementation/DefaultSessionRetriever.d.ts +3 -0
  31. package/lib/modules/extensions.full.module.d.ts +4 -0
  32. package/lib/modules/extensions.module.d.ts +4 -0
  33. package/lib/services/extensions.clipboard.service.d.ts +3 -0
  34. package/lib/services/extensions.dates.service.d.ts +3 -0
  35. package/lib/services/extensions.exports.service.d.ts +3 -0
  36. package/lib/services/extensions.hashing.service.d.ts +3 -0
  37. package/lib/services/extensions.messages.service.d.ts +3 -0
  38. package/lib/services/extensions.storage.service.d.ts +3 -0
  39. package/lib/services/extensions.utilities.service.d.ts +3 -0
  40. package/package.json +22 -10
  41. package/bundles/esfaenza-extensions.umd.js +0 -2435
  42. package/bundles/esfaenza-extensions.umd.js.map +0 -1
  43. package/esfaenza-extensions.metadata.json +0 -1
  44. package/esm2015/esfaenza-extensions.js +0 -7
  45. package/esm2015/lib/models/providers/implementation/DefaultStorageProvider.js +0 -79
  46. package/esm2015/lib/models/session/implementation/DefaultSessionRetriever.js +0 -26
  47. package/esm2015/lib/modules/extensions.full.module.js +0 -54
  48. package/esm2015/lib/modules/extensions.module.js +0 -24
  49. package/esm2015/lib/services/extensions.clipboard.service.js +0 -165
  50. package/esm2015/lib/services/extensions.dates.service.js +0 -224
  51. package/esm2015/lib/services/extensions.hashing.service.js +0 -306
  52. package/esm2015/lib/services/extensions.messages.service.js +0 -317
  53. package/esm2015/lib/services/extensions.storage.service.js +0 -100
  54. package/esm2015/lib/services/extensions.utilities.service.js +0 -185
  55. package/fesm2015/esfaenza-extensions.js.map +0 -1
@@ -1,224 +0,0 @@
1
- // Angular
2
- import { Injectable, Inject, Optional } from "@angular/core";
3
- // Modelli
4
- import { EXT_ALLOW_UTC, EXT_LOCALE } from "../tokens";
5
- /**
6
- * Service che fornisce dei metodi di estensione per la gestione/manipolazione delle date
7
- */
8
- export class DateService {
9
- /**
10
- * Costruttore
11
- *
12
- * @ignore
13
- */
14
- constructor(LOCALE, allowUtc) {
15
- var _a, _b, _c, _d, _e, _f, _g, _h;
16
- this.LOCALE = LOCALE;
17
- this.allowUtc = allowUtc;
18
- /**
19
- * Oggetto statico di localizzazione per i messaggi di questa Service
20
- */
21
- this.loc = {
22
- "SMALL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY", 'it-IT': "DD/MM/YYYY" },
23
- "FULL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
24
- "FULL_DATE_FORMAT_NO_SS": { 'en-US': "MM/DD/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
25
- "SMALL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY", 'it-IT': "DD/MM/YYYY" },
26
- "SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR": { 'en-US': "DD/MM/YYYY HH", 'it-IT': "DD/MM/YYYY HH" },
27
- "SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
28
- "FULL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
29
- "FULL_DATE_DISPLAY_FORMAT_NO_SS": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" }
30
- };
31
- /**
32
- * Oggetto di configurazione per tenere da conto le informazioni sui formati
33
- */
34
- this.cfg = {
35
- fulldate: "",
36
- fulldateDisplay: "",
37
- smallDate: "",
38
- fulldateNoSS: "",
39
- smallDateWithH: "",
40
- smallDateWithM: "",
41
- fulldateDisplayNoSS: ""
42
- };
43
- this.cfg.smallDate = this.loc["SMALL_DATE_FORMAT"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT'];
44
- this.cfg.fulldate = this.loc["FULL_DATE_FORMAT"][(_b = this.LOCALE) !== null && _b !== void 0 ? _b : 'it-IT'];
45
- this.cfg.fulldateNoSS = this.loc["FULL_DATE_FORMAT_NO_SS"][(_c = this.LOCALE) !== null && _c !== void 0 ? _c : 'it-IT'];
46
- this.cfg.fulldateDisplay = this.loc["FULL_DATE_DISPLAY_FORMAT"][(_d = this.LOCALE) !== null && _d !== void 0 ? _d : 'it-IT'];
47
- this.cfg.fulldateDisplayNoSS = this.loc["FULL_DATE_DISPLAY_FORMAT_NO_SS"][(_e = this.LOCALE) !== null && _e !== void 0 ? _e : 'it-IT'];
48
- this.cfg.smallDate = this.loc["SMALL_DATE_DISPLAY_FORMAT"][(_f = this.LOCALE) !== null && _f !== void 0 ? _f : 'it-IT'];
49
- this.cfg.smallDateWithH = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR"][(_g = this.LOCALE) !== null && _g !== void 0 ? _g : 'it-IT'];
50
- this.cfg.smallDateWithM = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE"][(_h = this.LOCALE) !== null && _h !== void 0 ? _h : 'it-IT'];
51
- }
52
- /**
53
- * Aggiusta una data in "istante finale" in base a qual è la parte di data significativa.
54
- *
55
- * Es. Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
56
- *
57
- * @param {any} date Data qualsiasi (Date, stringa, dayjs...), verrà ricondotta ad un oggetto dayJs
58
- * @param {'day' | 'hour' | 'minute'} timepart Parte significativa della data
59
- * @param {boolean} printSeconds Indica se effettuare la stampa dei secondi o no
60
- */
61
- adjustDateToFinalInstant(date, timepart, printSeconds = true) {
62
- let mydt = this.getDateConvertion(date);
63
- if (mydt == null)
64
- return "FE: Not a Date";
65
- let isZeroTime = mydt.startOf(timepart).valueOf() === mydt.valueOf();
66
- if (!isZeroTime)
67
- return printSeconds ? mydt.format(this.cfg.fulldateDisplay) : mydt.format(this.cfg.fulldateDisplayNoSS);
68
- let tmpValue = mydt.subtract(1, timepart);
69
- let value = "";
70
- // Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
71
- if (timepart == 'day')
72
- value = tmpValue.format(this.cfg.smallDate) + " 24:00" + (printSeconds ? ':00' : '');
73
- // Istante finale dei minuti: giorno 05/10/1992 04:00:00 --> 05/10/1992 03:60(:00)
74
- else if (timepart == 'hour')
75
- value = tmpValue.format(this.cfg.smallDateWithH) + ":60" + (printSeconds ? ':00' : '');
76
- // Istante finale dei secondi: giorno 05/10/1992 04:10:00 --> 05/10/1992 04:09:60
77
- else if (timepart == 'minute')
78
- value = tmpValue.format(this.cfg.smallDateWithM) + ":60";
79
- return value;
80
- }
81
- /**
82
- * Funzione che effettua l'ordinamento fra 2 date in base alla direzione specificata
83
- *
84
- * @param {any} a Prima data per il confronto
85
- * @param {any} b Seconda data per il confronto
86
- * @param {'asc' | 'desc'} direction Direzione rispetto a cui ordinare le due date
87
- *
88
- * @returns {number} 0 se le date sono uguali, 1 se la data A deve venire logicamente prima della data B, -1 altrimenti
89
- */
90
- dateSort(a, b, direction) {
91
- if (a < b)
92
- return direction == 'asc' ? 1 : -1;
93
- else if (a > b)
94
- return direction == 'asc' ? -1 : 1;
95
- // con a uguale a b
96
- return 0;
97
- }
98
- /**
99
- * Effettua il trim dei secondi da una data espressa come stringa
100
- *
101
- * @param {string} value Data espressa come stringa
102
- *
103
- * @returns {string} Data senza i secondi
104
- */
105
- trimSeconds(value) {
106
- //I numeri mangiati da dayjs spesso vengono ricondotti a date vere. Mi assicuro che se ci sono solo numeri proseguo
107
- if (!isNaN(value))
108
- return value;
109
- //Se non ho qualcosa del tipo XX/YY/ZZZZ aa:bb:cc di sicuro non è una data che mi interessa
110
- if (!/^\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d$/g.test(value))
111
- return value;
112
- //In questo caso mi arrivano valori che devono essere stampati as-is, solo tagliando i secondi
113
- return "'" + value.substr(0, value.length - 3);
114
- }
115
- /**
116
- * Data una lista di date Da e una lista di date A restituisce un oggetto rappresentante il range che include tutte le date passate
117
- *
118
- * @param {any[]} fromDates Lista dei Da
119
- * @param {any[]} toDates Lista dei A
120
- *
121
- * @returns {{ from: any, to: any }} Range di date Da - A che include tutti i valori di **fromDates** e **toDates**
122
- */
123
- getMinMaxDatesRange(fromDates, toDates) {
124
- let datesFroms = [];
125
- let datesTo = [];
126
- for (let i = 0; i < fromDates.length; i++) {
127
- let d = fromDates[i];
128
- var convertion = this.getDateConvertion(d);
129
- if (convertion)
130
- datesFroms.push(convertion);
131
- }
132
- for (let i = 0; i < toDates.length; i++) {
133
- let d = toDates[i];
134
- var convertion = this.getDateConvertion(d);
135
- if (convertion)
136
- datesTo.push(convertion);
137
- }
138
- return { from: dayjs.min(datesFroms), to: dayjs.max(datesTo) };
139
- }
140
- /**
141
- * Ottiene la conversione di una data in qualsiasi formato al formato standard DayJs
142
- *
143
- * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
144
- * @param {boolean} useUtc Indica se usare l'estensione utc di Dayjs per parsare la data o no
145
- *
146
- * @returns {any} Data in modalità DayJs
147
- */
148
- getDateConvertion(date, useUtc = false) {
149
- if (!date)
150
- return null;
151
- if (this.isDayJs(date))
152
- return date;
153
- if (this.isJsDate(date))
154
- return useUtc ? dayjs.utc(date) : dayjs(date);
155
- // Se non c'è la proprietà length vuol dire che non è una stringa e a questo punto non ho idea di che minchia sia
156
- let length = date.length;
157
- if (!length)
158
- return null;
159
- if (useUtc && !this.allowUtc)
160
- throw "@esfaenza/extensions: Richiesta data UTC ma da configurazione la libreria non lo supporta";
161
- // Per risparmiare chiamate a tentoni, in base alla lunghezza della stringa chiamo direttamente il metodo giusto,
162
- // controllando poi che mi generi una data come me la aspetto io
163
- let tryThis = null;
164
- let toCall = useUtc ? dayjs.utc : dayjs;
165
- // Se la data contiene la lettera "T" vuol dire che è una data del tipo 2020-10-15T00:00:00, direttamente parsabile dal dayjs col locale corretto.
166
- // Per il resto mi baso sulla lunghezza della stringa
167
- if (date.includes("T"))
168
- tryThis = toCall(date);
169
- else if (length == this.cfg.fulldate.length)
170
- tryThis = toCall(date, this.cfg.fulldate);
171
- else if (length == this.cfg.smallDate.length)
172
- tryThis = toCall(date, this.cfg.smallDate);
173
- else if (length == this.cfg.fulldateNoSS.length)
174
- tryThis = toCall(date, this.cfg.fulldateNoSS);
175
- if (tryThis.isValid())
176
- return tryThis;
177
- // Se niente funziona, null.
178
- // Ricondurre l'Input ad una data non è possibile.
179
- return null;
180
- }
181
- /**
182
- * Helper che restituisce **true** qualora l'oggetto passato fosse una data vera e propria, **false** altrimenti
183
- *
184
- * @param {any} check Oggetto da controllare
185
- *
186
- * @returns {boolean} Indicazione se l'oggetto è un vero Date di Javascript o no
187
- */
188
- isJsDate(check) {
189
- return check && Object.prototype.toString.call(check) === "[object Date]" && !isNaN(check);
190
- }
191
- /**
192
- * Helper che restituisce **true** qualora l'oggetto passato fosse un DayJs vero e proprio, **false** altrimenti
193
- *
194
- * @param {any} check Oggetto da controllare
195
- * @returns {boolean} Indicazione se l'oggetto è un vero DayJs o no
196
- */
197
- isDayJs(check) {
198
- // Non uso instanceof perché sarebbe estremamente più lento
199
- // Non uso nemmeno isDayjs() della libreria Dayjs dato che ha lo stesso problema: https://github.com/iamkun/dayjs/blob/06f88f425828b1ce96b737332d25145a95a4ee9d/src/index.js#L9
200
- return check.$D !== undefined && check.$M !== undefined && check.$y !== undefined;
201
- }
202
- /**
203
- * Ottiene la formattazione di una data in base alla versione richiesta "small" o "long" e a se stampare o meno i secondi
204
- *
205
- * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
206
- * @param {boolean} small Indica se formattarla con un formato breve (se **true**) o un formato più lungo (se **false**)
207
- *
208
- * @returns {string} Data formattata nel formato richiesto
209
- */
210
- getFormatted(date, small, seconds) {
211
- var date = this.getDateConvertion(date);
212
- if (!date)
213
- return null;
214
- return date.format(small ? this.cfg.smallDate : seconds ? this.cfg.fulldateDisplay : this.cfg.fulldateDisplayNoSS);
215
- }
216
- }
217
- DateService.decorators = [
218
- { type: Injectable }
219
- ];
220
- DateService.ctorParameters = () => [
221
- { type: String, decorators: [{ type: Optional }, { type: Inject, args: [EXT_LOCALE,] }] },
222
- { type: Boolean, decorators: [{ type: Optional }, { type: Inject, args: [EXT_ALLOW_UTC,] }] }
223
- ];
224
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5kYXRlcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXh0ZW5zaW9ucy9zcmMvbGliL3NlcnZpY2VzL2V4dGVuc2lvbnMuZGF0ZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxVQUFVO0FBQ1YsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdELFVBQVU7QUFDVixPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQVFyRDs7RUFFRTtBQUVILE1BQU0sT0FBTyxXQUFXO0lBNkJwQjs7OztPQUlHO0lBQ0gsWUFBMkQsTUFBYyxFQUE2QyxRQUFpQjs7UUFBNUUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUE2QyxhQUFRLEdBQVIsUUFBUSxDQUFTO1FBaEN2STs7V0FFRztRQUNLLFFBQUcsR0FBRztZQUNWLG1CQUFtQixFQUFFLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFO1lBQ3JFLGtCQUFrQixFQUFFLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRTtZQUN0Rix3QkFBd0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUU7WUFDdEYsMkJBQTJCLEVBQUUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUU7WUFDN0UscUNBQXFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUU7WUFDN0YsdUNBQXVDLEVBQUUsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFO1lBQ3JHLDBCQUEwQixFQUFFLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRTtZQUM5RixnQ0FBZ0MsRUFBRSxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUU7U0FDakcsQ0FBQztRQUVGOztXQUVHO1FBQ0ssUUFBRyxHQUFHO1lBQ1YsUUFBUSxFQUFFLEVBQUU7WUFDWixlQUFlLEVBQUUsRUFBRTtZQUNuQixTQUFTLEVBQUUsRUFBRTtZQUNiLFlBQVksRUFBRSxFQUFFO1lBQ2hCLGNBQWMsRUFBRSxFQUFFO1lBQ2xCLGNBQWMsRUFBRSxFQUFFO1lBQ2xCLG1CQUFtQixFQUFFLEVBQUU7U0FDMUIsQ0FBQTtRQVFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxNQUFBLElBQUksQ0FBQyxNQUFNLG1DQUFJLE9BQU8sQ0FBQyxDQUFDO1FBQzNFLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxNQUFBLElBQUksQ0FBQyxNQUFNLG1DQUFJLE9BQU8sQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxNQUFBLElBQUksQ0FBQyxNQUFNLG1DQUFJLE9BQU8sQ0FBQyxDQUFDO1FBQ25GLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxNQUFBLElBQUksQ0FBQyxNQUFNLG1DQUFJLE9BQU8sQ0FBQyxDQUFDO1FBQ3hGLElBQUksQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDLE1BQUEsSUFBSSxDQUFDLE1BQU0sbUNBQUksT0FBTyxDQUFDLENBQUM7UUFDbEcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLE1BQUEsSUFBSSxDQUFDLE1BQU0sbUNBQUksT0FBTyxDQUFDLENBQUM7UUFDbkYsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDLE1BQUEsSUFBSSxDQUFDLE1BQU0sbUNBQUksT0FBTyxDQUFDLENBQUM7UUFDbEcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDLE1BQUEsSUFBSSxDQUFDLE1BQU0sbUNBQUksT0FBTyxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksd0JBQXdCLENBQUMsSUFBUyxFQUFFLFFBQW1DLEVBQUUsZUFBd0IsSUFBSTtRQUN4RyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsSUFBSSxJQUFJLElBQUksSUFBSTtZQUFFLE9BQU8sZ0JBQWdCLENBQUM7UUFFMUMsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckUsSUFBSSxDQUFDLFVBQVU7WUFBRSxPQUFPLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUV6SCxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMxQyxJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7UUFFZixpRUFBaUU7UUFDakUsSUFBSSxRQUFRLElBQUksS0FBSztZQUNqQixLQUFLLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLFFBQVEsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUV6RixrRkFBa0Y7YUFDN0UsSUFBSSxRQUFRLElBQUksTUFBTTtZQUN2QixLQUFLLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUUzRixpRkFBaUY7YUFDNUUsSUFBSSxRQUFRLElBQUksUUFBUTtZQUN6QixLQUFLLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUU3RCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxRQUFRLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxTQUF5QjtRQUNyRCxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQUUsT0FBTyxTQUFTLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3pDLElBQUksQ0FBQyxHQUFHLENBQUM7WUFBRSxPQUFPLFNBQVMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFbkQsbUJBQW1CO1FBQ25CLE9BQU8sQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLFdBQVcsQ0FBQyxLQUFhO1FBQzVCLG1IQUFtSDtRQUNuSCxJQUFJLENBQUMsS0FBSyxDQUFNLEtBQUssQ0FBQztZQUNsQixPQUFPLEtBQUssQ0FBQztRQUVqQiwyRkFBMkY7UUFDM0YsSUFBSSxDQUFDLHdDQUF3QyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDckQsT0FBTyxLQUFLLENBQUM7UUFFakIsOEZBQThGO1FBQzlGLE9BQU8sR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxtQkFBbUIsQ0FBQyxTQUFnQixFQUFFLE9BQWM7UUFDdkQsSUFBSSxVQUFVLEdBQVUsRUFBRSxDQUFDO1FBQzNCLElBQUksT0FBTyxHQUFVLEVBQUUsQ0FBQztRQUV4QixLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFDeEM7WUFDSSxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckIsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLElBQUksVUFBVTtnQkFDVixVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQ25DO1FBRUQsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQ3RDO1lBQ0ksSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25CLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzQyxJQUFJLFVBQVU7Z0JBQ1YsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUNoQztRQUVELE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO0lBQ25FLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksaUJBQWlCLENBQUMsSUFBUyxFQUFFLFNBQWtCLEtBQUs7UUFDdkQsSUFBSSxDQUFDLElBQUk7WUFDTCxPQUFPLElBQUksQ0FBQztRQUVoQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQ2xCLE9BQU8sSUFBSSxDQUFDO1FBRWhCLElBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFDbEIsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVqRCxpSEFBaUg7UUFDakgsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUN6QixJQUFJLENBQUMsTUFBTTtZQUNQLE9BQU8sSUFBSSxDQUFDO1FBRWhCLElBQUksTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVE7WUFDeEIsTUFBTSwyRkFBMkYsQ0FBQztRQUV0RyxrSEFBa0g7UUFDbEgsZ0VBQWdFO1FBQ2hFLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQztRQUNuQixJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUV4QyxrSkFBa0o7UUFDbEoscURBQXFEO1FBQ3JELElBQWEsSUFBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7WUFDNUIsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUN0QixJQUFJLE1BQU0sSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNO1lBQ3ZDLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDekMsSUFBSSxNQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsTUFBTTtZQUN4QyxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQzFDLElBQUksTUFBTSxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU07WUFDM0MsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUVqRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUU7WUFDakIsT0FBTyxPQUFPLENBQUM7UUFFbkIsNkJBQTZCO1FBQzdCLGtEQUFrRDtRQUNsRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssUUFBUSxDQUFDLEtBQVU7UUFDdkIsT0FBTyxLQUFLLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLGVBQWUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTSxPQUFPLENBQUMsS0FBVTtRQUN2QiwyREFBMkQ7UUFDM0QsK0tBQStLO1FBQy9LLE9BQU8sS0FBSyxDQUFDLEVBQUUsS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLEVBQUUsS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLEVBQUUsS0FBSyxTQUFTLENBQUM7SUFDdEYsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxZQUFZLENBQUMsSUFBUyxFQUFFLEtBQWMsRUFBRSxPQUFnQjtRQUMzRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLElBQUksQ0FBQztRQUV2QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3ZILENBQUM7OztZQTFPSixVQUFVOzs7eUNBbUNhLFFBQVEsWUFBSSxNQUFNLFNBQUMsVUFBVTswQ0FBMkIsUUFBUSxZQUFJLE1BQU0sU0FBQyxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5ndWxhclxyXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QsIE9wdGlvbmFsIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuXHJcbi8vIE1vZGVsbGlcclxuaW1wb3J0IHsgRVhUX0FMTE9XX1VUQywgRVhUX0xPQ0FMRSB9IGZyb20gXCIuLi90b2tlbnNcIjtcclxuXHJcbi8qKlxyXG4gKiBEaWNoaWFyYXppb25lIGRlbGxhIHZhcmlhYmlsZSBnbG9iYWxlIGRheWpzLiBMJ29uZXJlIGRpIFwiY3JlYXJsYVwiIMOoIGFmZmlkYXRvIGFsbCdhcHBsaWNhemlvbmUgY2hlIHV0aWxpenphIHF1ZXN0YSBsaWJyZXJpYSwgXHJcbiAqIGNoZSBkb3Zyw6AgaW1wb3J0YXJlIGxvIHNjcmlwdCBnbG9iYWxlIGRpIGRheWpzIG5lbGxhIENMSVxyXG4gKi9cclxuIGRlY2xhcmUgdmFyIGRheWpzOiBhbnk7XHJcblxyXG4gLyoqXHJcbiAqIFNlcnZpY2UgY2hlIGZvcm5pc2NlIGRlaSBtZXRvZGkgZGkgZXN0ZW5zaW9uZSBwZXIgbGEgZ2VzdGlvbmUvbWFuaXBvbGF6aW9uZSBkZWxsZSBkYXRlXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBEYXRlU2VydmljZSB7XHJcbiAgICBcclxuICAgIC8qKlxyXG4gICAgICogT2dnZXR0byBzdGF0aWNvIGRpIGxvY2FsaXp6YXppb25lIHBlciBpIG1lc3NhZ2dpIGRpIHF1ZXN0YSBTZXJ2aWNlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgbG9jID0ge1xyXG4gICAgICAgIFwiU01BTExfREFURV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIk1NL0REL1lZWVlcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZXCIgfSxcclxuICAgICAgICBcIkZVTExfREFURV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIk1NL0REL1lZWVkgSEg6bW06c3NcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZIEhIOm1tOnNzXCIgfSxcclxuICAgICAgICBcIkZVTExfREFURV9GT1JNQVRfTk9fU1NcIjogeyAnZW4tVVMnOiBcIk1NL0REL1lZWVkgSEg6bW1cIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZIEhIOm1tXCIgfSxcclxuICAgICAgICBcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIkREL01NL1lZWVlcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZXCIgfSxcclxuICAgICAgICBcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRfV0lUSF9IT1VSXCI6IHsgJ2VuLVVTJzogXCJERC9NTS9ZWVlZIEhIXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWSBISFwiIH0sXHJcbiAgICAgICAgXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUX1dJVEhfTUlOVVRFXCI6IHsgJ2VuLVVTJzogXCJERC9NTS9ZWVlZIEhIOm1tXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWSBISDptbVwiIH0sXHJcbiAgICAgICAgXCJGVUxMX0RBVEVfRElTUExBWV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIkREL01NL1lZWVkgSEg6bW06c3NcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZIEhIOm1tOnNzXCIgfSxcclxuICAgICAgICBcIkZVTExfREFURV9ESVNQTEFZX0ZPUk1BVF9OT19TU1wiOiB7ICdlbi1VUyc6IFwiREQvTU0vWVlZWSBISDptbVwiLCAnaXQtSVQnOiBcIkREL01NL1lZWVkgSEg6bW1cIiB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2dnZXR0byBkaSBjb25maWd1cmF6aW9uZSBwZXIgdGVuZXJlIGRhIGNvbnRvIGxlIGluZm9ybWF6aW9uaSBzdWkgZm9ybWF0aVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNmZyA9IHtcclxuICAgICAgICBmdWxsZGF0ZTogXCJcIixcclxuICAgICAgICBmdWxsZGF0ZURpc3BsYXk6IFwiXCIsXHJcbiAgICAgICAgc21hbGxEYXRlOiBcIlwiLFxyXG4gICAgICAgIGZ1bGxkYXRlTm9TUzogXCJcIixcclxuICAgICAgICBzbWFsbERhdGVXaXRoSDogXCJcIixcclxuICAgICAgICBzbWFsbERhdGVXaXRoTTogXCJcIixcclxuICAgICAgICBmdWxsZGF0ZURpc3BsYXlOb1NTOiBcIlwiXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb3N0cnV0dG9yZVxyXG4gICAgICogXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBASW5qZWN0KEVYVF9MT0NBTEUpIHByaXZhdGUgTE9DQUxFOiBzdHJpbmcsIEBPcHRpb25hbCgpIEBJbmplY3QoRVhUX0FMTE9XX1VUQykgcHJpdmF0ZSBhbGxvd1V0YzogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuY2ZnLnNtYWxsRGF0ZSA9IHRoaXMubG9jW1wiU01BTExfREFURV9GT1JNQVRcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ107XHJcbiAgICAgICAgdGhpcy5jZmcuZnVsbGRhdGUgPSB0aGlzLmxvY1tcIkZVTExfREFURV9GT1JNQVRcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ107XHJcbiAgICAgICAgdGhpcy5jZmcuZnVsbGRhdGVOb1NTID0gdGhpcy5sb2NbXCJGVUxMX0RBVEVfRk9STUFUX05PX1NTXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLmZ1bGxkYXRlRGlzcGxheSA9IHRoaXMubG9jW1wiRlVMTF9EQVRFX0RJU1BMQVlfRk9STUFUXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLmZ1bGxkYXRlRGlzcGxheU5vU1MgID10aGlzLmxvY1tcIkZVTExfREFURV9ESVNQTEFZX0ZPUk1BVF9OT19TU1wiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXTtcclxuICAgICAgICB0aGlzLmNmZy5zbWFsbERhdGUgPSB0aGlzLmxvY1tcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ107XHJcbiAgICAgICAgdGhpcy5jZmcuc21hbGxEYXRlV2l0aEggPSB0aGlzLmxvY1tcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRfV0lUSF9IT1VSXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLnNtYWxsRGF0ZVdpdGhNID0gdGhpcy5sb2NbXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUX1dJVEhfTUlOVVRFXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWdnaXVzdGEgdW5hIGRhdGEgaW4gXCJpc3RhbnRlIGZpbmFsZVwiIGluIGJhc2UgYSBxdWFsIMOoIGxhIHBhcnRlIGRpIGRhdGEgc2lnbmlmaWNhdGl2YS5cclxuICAgICAqIFxyXG4gICAgICogRXMuIElzdGFudGUgZmluYWxlIGRlbGxlIG9yZTogMDUvMTAvMTk5MiAtLT4gMDQvMTAvMTk5MiAyNDowMCg6MDApXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBkYXRlIERhdGEgcXVhbHNpYXNpIChEYXRlLCBzdHJpbmdhLCBkYXlqcy4uLiksIHZlcnLDoCByaWNvbmRvdHRhIGFkIHVuIG9nZ2V0dG8gZGF5SnNcclxuICAgICAqIEBwYXJhbSB7J2RheScgfCAnaG91cicgfCAnbWludXRlJ30gdGltZXBhcnQgUGFydGUgc2lnbmlmaWNhdGl2YSBkZWxsYSBkYXRhXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHByaW50U2Vjb25kcyBJbmRpY2Egc2UgZWZmZXR0dWFyZSBsYSBzdGFtcGEgZGVpIHNlY29uZGkgbyBub1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRqdXN0RGF0ZVRvRmluYWxJbnN0YW50KGRhdGU6IGFueSwgdGltZXBhcnQ6ICdkYXknIHwgJ2hvdXInIHwgJ21pbnV0ZScsIHByaW50U2Vjb25kczogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmcge1xyXG4gICAgICAgIGxldCBteWR0ID0gdGhpcy5nZXREYXRlQ29udmVydGlvbihkYXRlKTtcclxuICAgICAgICBpZiAobXlkdCA9PSBudWxsKSByZXR1cm4gXCJGRTogTm90IGEgRGF0ZVwiO1xyXG5cclxuICAgICAgICBsZXQgaXNaZXJvVGltZSA9IG15ZHQuc3RhcnRPZih0aW1lcGFydCkudmFsdWVPZigpID09PSBteWR0LnZhbHVlT2YoKTtcclxuICAgICAgICBpZiAoIWlzWmVyb1RpbWUpIHJldHVybiBwcmludFNlY29uZHMgPyBteWR0LmZvcm1hdCh0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXkpIDogbXlkdC5mb3JtYXQodGhpcy5jZmcuZnVsbGRhdGVEaXNwbGF5Tm9TUyk7XHJcblxyXG4gICAgICAgIGxldCB0bXBWYWx1ZSA9IG15ZHQuc3VidHJhY3QoMSwgdGltZXBhcnQpO1xyXG4gICAgICAgIGxldCB2YWx1ZSA9IFwiXCI7XHJcblxyXG4gICAgICAgIC8vIElzdGFudGUgZmluYWxlIGRlbGxlIG9yZTogMDUvMTAvMTk5MiAtLT4gMDQvMTAvMTk5MiAyNDowMCg6MDApXHJcbiAgICAgICAgaWYgKHRpbWVwYXJ0ID09ICdkYXknKVxyXG4gICAgICAgICAgICB2YWx1ZSA9IHRtcFZhbHVlLmZvcm1hdCh0aGlzLmNmZy5zbWFsbERhdGUpICsgXCIgMjQ6MDBcIiArIChwcmludFNlY29uZHMgPyAnOjAwJyA6ICcnKTtcclxuXHJcbiAgICAgICAgLy8gSXN0YW50ZSBmaW5hbGUgZGVpIG1pbnV0aTogZ2lvcm5vIDA1LzEwLzE5OTIgMDQ6MDA6MDAgLS0+IDA1LzEwLzE5OTIgMDM6NjAoOjAwKVxyXG4gICAgICAgIGVsc2UgaWYgKHRpbWVwYXJ0ID09ICdob3VyJylcclxuICAgICAgICAgICAgdmFsdWUgPSB0bXBWYWx1ZS5mb3JtYXQodGhpcy5jZmcuc21hbGxEYXRlV2l0aEgpICsgXCI6NjBcIiArIChwcmludFNlY29uZHMgPyAnOjAwJyA6ICcnKTtcclxuXHJcbiAgICAgICAgLy8gSXN0YW50ZSBmaW5hbGUgZGVpIHNlY29uZGk6IGdpb3JubyAwNS8xMC8xOTkyIDA0OjEwOjAwIC0tPiAwNS8xMC8xOTkyIDA0OjA5OjYwXHJcbiAgICAgICAgZWxzZSBpZiAodGltZXBhcnQgPT0gJ21pbnV0ZScpXHJcbiAgICAgICAgICAgIHZhbHVlID0gdG1wVmFsdWUuZm9ybWF0KHRoaXMuY2ZnLnNtYWxsRGF0ZVdpdGhNKSArIFwiOjYwXCI7XHJcblxyXG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bnppb25lIGNoZSBlZmZldHR1YSBsJ29yZGluYW1lbnRvIGZyYSAyIGRhdGUgaW4gYmFzZSBhbGxhIGRpcmV6aW9uZSBzcGVjaWZpY2F0YVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gYSBQcmltYSBkYXRhIHBlciBpbCBjb25mcm9udG9cclxuICAgICAqIEBwYXJhbSB7YW55fSBiIFNlY29uZGEgZGF0YSBwZXIgaWwgY29uZnJvbnRvXHJcbiAgICAgKiBAcGFyYW0geydhc2MnIHwgJ2Rlc2MnfSBkaXJlY3Rpb24gRGlyZXppb25lIHJpc3BldHRvIGEgY3VpIG9yZGluYXJlIGxlIGR1ZSBkYXRlXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IDAgc2UgbGUgZGF0ZSBzb25vIHVndWFsaSwgMSBzZSBsYSBkYXRhIEEgZGV2ZSB2ZW5pcmUgbG9naWNhbWVudGUgcHJpbWEgZGVsbGEgZGF0YSBCLCAtMSBhbHRyaW1lbnRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkYXRlU29ydChhOiBhbnksIGI6IGFueSwgZGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKGEgPCBiKSByZXR1cm4gZGlyZWN0aW9uID09ICdhc2MnID8gMSA6IC0xO1xyXG4gICAgICAgIGVsc2UgaWYgKGEgPiBiKSByZXR1cm4gZGlyZWN0aW9uID09ICdhc2MnID8gLTEgOiAxO1xyXG5cclxuICAgICAgICAvLyBjb24gYSB1Z3VhbGUgYSBiXHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFZmZldHR1YSBpbCB0cmltIGRlaSBzZWNvbmRpIGRhIHVuYSBkYXRhIGVzcHJlc3NhIGNvbWUgc3RyaW5nYVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgRGF0YSBlc3ByZXNzYSBjb21lIHN0cmluZ2FcclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gRGF0YSBzZW56YSBpIHNlY29uZGlcclxuICAgICAqL1xyXG4gICAgcHVibGljIHRyaW1TZWNvbmRzKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIC8vSSBudW1lcmkgbWFuZ2lhdGkgZGEgZGF5anMgc3Blc3NvIHZlbmdvbm8gcmljb25kb3R0aSBhIGRhdGUgdmVyZS4gTWkgYXNzaWN1cm8gY2hlIHNlIGNpIHNvbm8gc29sbyBudW1lcmkgcHJvc2VndW9cclxuICAgICAgICBpZiAoIWlzTmFOKDxhbnk+dmFsdWUpKVxyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcblxyXG4gICAgICAgIC8vU2Ugbm9uIGhvIHF1YWxjb3NhIGRlbCB0aXBvIFhYL1lZL1paWlogYWE6YmI6Y2MgZGkgc2ljdXJvIG5vbiDDqCB1bmEgZGF0YSBjaGUgbWkgaW50ZXJlc3NhXHJcbiAgICAgICAgaWYgKCEvXlxcZFxcZFxcL1xcZFxcZFxcL1xcZFxcZFxcZFxcZCBcXGRcXGQ6XFxkXFxkOlxcZFxcZCQvZy50ZXN0KHZhbHVlKSlcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICAvL0luIHF1ZXN0byBjYXNvIG1pIGFycml2YW5vIHZhbG9yaSBjaGUgZGV2b25vIGVzc2VyZSBzdGFtcGF0aSBhcy1pcywgc29sbyB0YWdsaWFuZG8gaSBzZWNvbmRpXHJcbiAgICAgICAgcmV0dXJuIFwiJ1wiICsgdmFsdWUuc3Vic3RyKDAsIHZhbHVlLmxlbmd0aCAtIDMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0YSB1bmEgbGlzdGEgZGkgZGF0ZSBEYSBlIHVuYSBsaXN0YSBkaSBkYXRlIEEgcmVzdGl0dWlzY2UgdW4gb2dnZXR0byByYXBwcmVzZW50YW50ZSBpbCByYW5nZSBjaGUgaW5jbHVkZSB0dXR0ZSBsZSBkYXRlIHBhc3NhdGVcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gZnJvbURhdGVzIExpc3RhIGRlaSBEYVxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gdG9EYXRlcyBMaXN0YSBkZWkgQVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7eyBmcm9tOiBhbnksIHRvOiBhbnkgfX0gUmFuZ2UgZGkgZGF0ZSBEYSAtIEEgY2hlIGluY2x1ZGUgdHV0dGkgaSB2YWxvcmkgZGkgKipmcm9tRGF0ZXMqKiBlICoqdG9EYXRlcyoqXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRNaW5NYXhEYXRlc1JhbmdlKGZyb21EYXRlczogYW55W10sIHRvRGF0ZXM6IGFueVtdKTogeyBmcm9tOiBhbnksIHRvOiBhbnkgfSB7XHJcbiAgICAgICAgbGV0IGRhdGVzRnJvbXM6IGFueVtdID0gW107XHJcbiAgICAgICAgbGV0IGRhdGVzVG86IGFueVtdID0gW107XHJcblxyXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBmcm9tRGF0ZXMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICBsZXQgZCA9IGZyb21EYXRlc1tpXTtcclxuICAgICAgICAgICAgdmFyIGNvbnZlcnRpb24gPSB0aGlzLmdldERhdGVDb252ZXJ0aW9uKGQpO1xyXG4gICAgICAgICAgICBpZiAoY29udmVydGlvbilcclxuICAgICAgICAgICAgICAgIGRhdGVzRnJvbXMucHVzaChjb252ZXJ0aW9uKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB0b0RhdGVzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgbGV0IGQgPSB0b0RhdGVzW2ldO1xyXG4gICAgICAgICAgICB2YXIgY29udmVydGlvbiA9IHRoaXMuZ2V0RGF0ZUNvbnZlcnRpb24oZCk7XHJcbiAgICAgICAgICAgIGlmIChjb252ZXJ0aW9uKVxyXG4gICAgICAgICAgICAgICAgZGF0ZXNUby5wdXNoKGNvbnZlcnRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHsgZnJvbTogZGF5anMubWluKGRhdGVzRnJvbXMpLCB0bzogZGF5anMubWF4KGRhdGVzVG8pIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPdHRpZW5lIGxhIGNvbnZlcnNpb25lIGRpIHVuYSBkYXRhIGluIHF1YWxzaWFzaSBmb3JtYXRvIGFsIGZvcm1hdG8gc3RhbmRhcmQgRGF5SnNcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGRhdGUgT2dnZXR0byByYXBwcmVzZW50YW50ZSB1bmEgZGF0YS4gUG90cmViYmUgZXNzZXJlIHVuYSBzdHJpbmdhLCB1biBEYXRlIG8gZ2nDoCB1biBEYXlKc1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSB1c2VVdGMgSW5kaWNhIHNlIHVzYXJlIGwnZXN0ZW5zaW9uZSB1dGMgZGkgRGF5anMgcGVyIHBhcnNhcmUgbGEgZGF0YSBvIG5vXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHthbnl9IERhdGEgaW4gbW9kYWxpdMOgIERheUpzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXREYXRlQ29udmVydGlvbihkYXRlOiBhbnksIHVzZVV0YzogYm9vbGVhbiA9IGZhbHNlKTogYW55IHtcclxuICAgICAgICBpZiAoIWRhdGUpXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pc0RheUpzKGRhdGUpKVxyXG4gICAgICAgICAgICByZXR1cm4gZGF0ZTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5pc0pzRGF0ZShkYXRlKSlcclxuICAgICAgICAgICAgcmV0dXJuIHVzZVV0YyA/IGRheWpzLnV0YyhkYXRlKTogZGF5anMoZGF0ZSk7XHJcblxyXG4gICAgICAgIC8vIFNlIG5vbiBjJ8OoIGxhIHByb3ByaWV0w6AgbGVuZ3RoIHZ1b2wgZGlyZSBjaGUgbm9uIMOoIHVuYSBzdHJpbmdhIGUgYSBxdWVzdG8gcHVudG8gbm9uIGhvIGlkZWEgZGkgY2hlIG1pbmNoaWEgc2lhXHJcbiAgICAgICAgbGV0IGxlbmd0aCA9IGRhdGUubGVuZ3RoO1xyXG4gICAgICAgIGlmICghbGVuZ3RoKVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHVzZVV0YyAmJiAhdGhpcy5hbGxvd1V0YylcclxuICAgICAgICAgICAgdGhyb3cgXCJAZXNmYWVuemEvZXh0ZW5zaW9uczogUmljaGllc3RhIGRhdGEgVVRDIG1hIGRhIGNvbmZpZ3VyYXppb25lIGxhIGxpYnJlcmlhIG5vbiBsbyBzdXBwb3J0YVwiO1xyXG5cclxuICAgICAgICAvLyBQZXIgcmlzcGFybWlhcmUgY2hpYW1hdGUgYSB0ZW50b25pLCBpbiBiYXNlIGFsbGEgbHVuZ2hlenphIGRlbGxhIHN0cmluZ2EgY2hpYW1vIGRpcmV0dGFtZW50ZSBpbCBtZXRvZG8gZ2l1c3RvLCBcclxuICAgICAgICAvLyBjb250cm9sbGFuZG8gcG9pIGNoZSBtaSBnZW5lcmkgdW5hIGRhdGEgY29tZSBtZSBsYSBhc3BldHRvIGlvXHJcbiAgICAgICAgbGV0IHRyeVRoaXMgPSBudWxsO1xyXG4gICAgICAgIGxldCB0b0NhbGwgPSB1c2VVdGMgPyBkYXlqcy51dGMgOiBkYXlqcztcclxuXHJcbiAgICAgICAgLy8gU2UgbGEgZGF0YSBjb250aWVuZSBsYSBsZXR0ZXJhIFwiVFwiIHZ1b2wgZGlyZSBjaGUgw6ggdW5hIGRhdGEgZGVsIHRpcG8gMjAyMC0xMC0xNVQwMDowMDowMCwgZGlyZXR0YW1lbnRlIHBhcnNhYmlsZSBkYWwgZGF5anMgY29sIGxvY2FsZSBjb3JyZXR0by5cclxuICAgICAgICAvLyBQZXIgaWwgcmVzdG8gbWkgYmFzbyBzdWxsYSBsdW5naGV6emEgZGVsbGEgc3RyaW5nYVxyXG4gICAgICAgIGlmICgoPHN0cmluZz5kYXRlKS5pbmNsdWRlcyhcIlRcIikpXHJcbiAgICAgICAgICAgIHRyeVRoaXMgPSB0b0NhbGwoZGF0ZSk7XHJcbiAgICAgICAgZWxzZSBpZiAobGVuZ3RoID09IHRoaXMuY2ZnLmZ1bGxkYXRlLmxlbmd0aClcclxuICAgICAgICAgICAgdHJ5VGhpcyA9IHRvQ2FsbChkYXRlLCB0aGlzLmNmZy5mdWxsZGF0ZSk7XHJcbiAgICAgICAgZWxzZSBpZiAobGVuZ3RoID09IHRoaXMuY2ZnLnNtYWxsRGF0ZS5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRyeVRoaXMgPSB0b0NhbGwoZGF0ZSwgdGhpcy5jZmcuc21hbGxEYXRlKTtcclxuICAgICAgICBlbHNlIGlmIChsZW5ndGggPT0gdGhpcy5jZmcuZnVsbGRhdGVOb1NTLmxlbmd0aClcclxuICAgICAgICAgICAgdHJ5VGhpcyA9IHRvQ2FsbChkYXRlLCB0aGlzLmNmZy5mdWxsZGF0ZU5vU1MpXHJcblxyXG4gICAgICAgIGlmICh0cnlUaGlzLmlzVmFsaWQoKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRyeVRoaXM7XHJcblxyXG4gICAgICAgIC8vIFNlIG5pZW50ZSBmdW56aW9uYSwgbnVsbC4gXHJcbiAgICAgICAgLy8gUmljb25kdXJyZSBsJ0lucHV0IGFkIHVuYSBkYXRhIG5vbiDDqCBwb3NzaWJpbGUuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgY2hlIHJlc3RpdHVpc2NlICoqdHJ1ZSoqIHF1YWxvcmEgbCdvZ2dldHRvIHBhc3NhdG8gZm9zc2UgdW5hIGRhdGEgdmVyYSBlIHByb3ByaWEsICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBjaGVjayBPZ2dldHRvIGRhIGNvbnRyb2xsYXJlXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBJbmRpY2F6aW9uZSBzZSBsJ29nZ2V0dG8gw6ggdW4gdmVybyBEYXRlIGRpIEphdmFzY3JpcHQgbyBub1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzSnNEYXRlKGNoZWNrOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gY2hlY2sgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGNoZWNrKSA9PT0gXCJbb2JqZWN0IERhdGVdXCIgJiYgIWlzTmFOKGNoZWNrKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBjaGUgcmVzdGl0dWlzY2UgKip0cnVlKiogcXVhbG9yYSBsJ29nZ2V0dG8gcGFzc2F0byBmb3NzZSB1biBEYXlKcyB2ZXJvIGUgcHJvcHJpbywgKipmYWxzZSoqIGFsdHJpbWVudGlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGNoZWNrIE9nZ2V0dG8gZGEgY29udHJvbGxhcmVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBJbmRpY2F6aW9uZSBzZSBsJ29nZ2V0dG8gw6ggdW4gdmVybyBEYXlKcyBvIG5vXHJcbiAgICAgKi9cclxuICAgICBwcml2YXRlIGlzRGF5SnMoY2hlY2s6IGFueSk6IGJvb2xlYW4ge1xyXG4gICAgICAgIC8vIE5vbiB1c28gaW5zdGFuY2VvZiBwZXJjaMOpIHNhcmViYmUgZXN0cmVtYW1lbnRlIHBpw7kgbGVudG9cclxuICAgICAgICAvLyBOb24gdXNvIG5lbW1lbm8gaXNEYXlqcygpIGRlbGxhIGxpYnJlcmlhIERheWpzIGRhdG8gY2hlIGhhIGxvIHN0ZXNzbyBwcm9ibGVtYTogaHR0cHM6Ly9naXRodWIuY29tL2lhbWt1bi9kYXlqcy9ibG9iLzA2Zjg4ZjQyNTgyOGIxY2U5NmI3MzczMzJkMjUxNDVhOTVhNGVlOWQvc3JjL2luZGV4LmpzI0w5XHJcbiAgICAgICAgcmV0dXJuIGNoZWNrLiREICE9PSB1bmRlZmluZWQgJiYgY2hlY2suJE0gIT09IHVuZGVmaW5lZCAmJiBjaGVjay4keSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3R0aWVuZSBsYSBmb3JtYXR0YXppb25lIGRpIHVuYSBkYXRhIGluIGJhc2UgYWxsYSB2ZXJzaW9uZSByaWNoaWVzdGEgXCJzbWFsbFwiIG8gXCJsb25nXCIgZSBhIHNlIHN0YW1wYXJlIG8gbWVubyBpIHNlY29uZGlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGRhdGUgT2dnZXR0byByYXBwcmVzZW50YW50ZSB1bmEgZGF0YS4gUG90cmViYmUgZXNzZXJlIHVuYSBzdHJpbmdhLCB1biBEYXRlIG8gZ2nDoCB1biBEYXlKc1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBzbWFsbCBJbmRpY2Egc2UgZm9ybWF0dGFybGEgY29uIHVuIGZvcm1hdG8gYnJldmUgKHNlICoqdHJ1ZSoqKSBvIHVuIGZvcm1hdG8gcGnDuSBsdW5nbyAoc2UgKipmYWxzZSoqKVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBEYXRhIGZvcm1hdHRhdGEgbmVsIGZvcm1hdG8gcmljaGllc3RvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRGb3JtYXR0ZWQoZGF0ZTogYW55LCBzbWFsbDogYm9vbGVhbiwgc2Vjb25kczogYm9vbGVhbik6IHN0cmluZyB7XHJcbiAgICAgICAgdmFyIGRhdGUgPSB0aGlzLmdldERhdGVDb252ZXJ0aW9uKGRhdGUpO1xyXG4gICAgICAgIGlmICghZGF0ZSkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIHJldHVybiBkYXRlLmZvcm1hdChzbWFsbCA/IHRoaXMuY2ZnLnNtYWxsRGF0ZSA6IHNlY29uZHMgPyB0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXkgOiB0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXlOb1NTKTtcclxuICAgIH1cclxufSJdfQ==