@ngx-pwa/local-storage 12.1.0 → 13.0.2

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 (38) hide show
  1. package/README.md +6 -18
  2. package/{esm2015/lib/databases/exceptions.js → esm2020/lib/databases/exceptions.mjs} +1 -1
  3. package/esm2020/lib/databases/indexeddb-database.mjs +326 -0
  4. package/{esm2015/lib/databases/local-database.js → esm2020/lib/databases/local-database.mjs} +7 -7
  5. package/{esm2015/lib/databases/localstorage-database.js → esm2020/lib/databases/localstorage-database.mjs} +3 -3
  6. package/{esm2015/lib/databases/memory-database.js → esm2020/lib/databases/memory-database.mjs} +3 -3
  7. package/{esm2015/lib/storage.module.js → esm2020/lib/storage.module.mjs} +4 -4
  8. package/{esm2015/lib/storages/exceptions.js → esm2020/lib/storages/exceptions.mjs} +1 -1
  9. package/esm2020/lib/storages/local-storage.service.mjs +83 -0
  10. package/{esm2015/lib/storages/storage-map.service.js → esm2020/lib/storages/storage-map.service.mjs} +5 -5
  11. package/{esm2015/lib/tokens.js → esm2020/lib/tokens.mjs} +0 -0
  12. package/{esm2015/lib/validation/json-schema.js → esm2020/lib/validation/json-schema.mjs} +0 -0
  13. package/esm2020/lib/validation/json-validator.mjs +243 -0
  14. package/{esm2015/ngx-pwa-local-storage.js → esm2020/ngx-pwa-local-storage.mjs} +0 -0
  15. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  16. package/fesm2015/ngx-pwa-local-storage.mjs +1389 -0
  17. package/fesm2015/ngx-pwa-local-storage.mjs.map +1 -0
  18. package/{fesm2015/ngx-pwa-local-storage.js → fesm2020/ngx-pwa-local-storage.mjs} +40 -38
  19. package/fesm2020/ngx-pwa-local-storage.mjs.map +1 -0
  20. package/package.json +25 -12
  21. package/schematics/migration.json +5 -0
  22. package/schematics/ng-add/index.js +14 -3
  23. package/schematics/ng-add/index.js.map +1 -1
  24. package/schematics/ng-add/schema.json +1 -1
  25. package/schematics/ng-update/index.d.ts +1 -0
  26. package/schematics/ng-update/index.js +18 -5
  27. package/schematics/ng-update/index.js.map +1 -1
  28. package/schematics/utility/config.d.ts +1 -1
  29. package/schematics/utility/config.js +11 -11
  30. package/schematics/utility/config.js.map +1 -1
  31. package/schematics/utility/module.js +3 -3
  32. package/schematics/utility/module.js.map +1 -1
  33. package/bundles/ngx-pwa-local-storage.umd.js +0 -1846
  34. package/bundles/ngx-pwa-local-storage.umd.js.map +0 -1
  35. package/esm2015/lib/databases/indexeddb-database.js +0 -327
  36. package/esm2015/lib/storages/local-storage.service.js +0 -80
  37. package/esm2015/lib/validation/json-validator.js +0 -242
  38. package/fesm2015/ngx-pwa-local-storage.js.map +0 -1
@@ -1,327 +0,0 @@
1
- import { Injectable, Inject } from '@angular/core';
2
- import { ReplaySubject, fromEvent, of, throwError, race } from 'rxjs';
3
- import { map, mergeMap, first, takeWhile, tap, mapTo } from 'rxjs/operators';
4
- import { IDB_DB_NAME, IDB_STORE_NAME, DEFAULT_IDB_STORE_NAME, IDB_DB_VERSION, DEFAULT_IDB_DB_NAME, DEFAULT_IDB_DB_VERSION, IDB_NO_WRAP, DEFAULT_IDB_NO_WRAP } from '../tokens';
5
- import { IDBBrokenError } from './exceptions';
6
- import * as i0 from "@angular/core";
7
- export class IndexedDBDatabase {
8
- /**
9
- * Constructor params are provided by Angular (but can also be passed manually in tests)
10
- * @param dbName `indexedDB` database name
11
- * @param storeName `indexedDB` store name
12
- * @param dbVersion `indexedDB` database version
13
- * @param noWrap Flag to not wrap `indexedDB` values for interoperability or to wrap for backward compatibility
14
- */
15
- constructor(dbName = DEFAULT_IDB_DB_NAME, storeName = DEFAULT_IDB_STORE_NAME, dbVersion = DEFAULT_IDB_DB_VERSION, noWrap = DEFAULT_IDB_NO_WRAP) {
16
- /**
17
- * `indexedDB` database connection, wrapped in a RxJS `ReplaySubject` to be able to access the connection
18
- * even after the connection success event happened
19
- */
20
- this.database = new ReplaySubject(1);
21
- /**
22
- * Index used when wrapping value. *For backward compatibility only.*
23
- */
24
- this.wrapIndex = 'value';
25
- this.dbName = dbName;
26
- this.storeName = storeName;
27
- this.dbVersion = dbVersion;
28
- this.noWrap = noWrap;
29
- /* Connect to `indexedDB`, with prefix if provided by the user */
30
- this.connect();
31
- }
32
- /**
33
- * Information about `indexedDB` connection. *Only useful for interoperability.*
34
- * @returns `indexedDB` database name, store name and database version
35
- */
36
- get backingStore() {
37
- return {
38
- database: this.dbName,
39
- store: this.storeName,
40
- version: this.dbVersion,
41
- };
42
- }
43
- /**
44
- * Number of items in our `indexedDB` database and object store
45
- */
46
- get size() {
47
- /* Open a transaction in read-only mode */
48
- return this.transaction('readonly').pipe(mergeMap((transactionData) => {
49
- const { store, events } = transactionData;
50
- /* Request to know the number of items */
51
- const request = store.count();
52
- /* Return the result */
53
- return events.pipe(map(() => request.result));
54
- }),
55
- /* The observable will complete after the first value */
56
- first());
57
- }
58
- /**
59
- * Gets an item value in our `indexedDB` store
60
- * @param key The item's key
61
- * @returns The item's value if the key exists, `undefined` otherwise, wrapped in an RxJS `Observable`
62
- */
63
- get(key) {
64
- /* Open a transaction in read-only mode */
65
- return this.transaction('readonly').pipe(mergeMap((transactionData) => {
66
- const { store, events } = transactionData;
67
- /* Request the value with the key provided by the user */
68
- const request = store.get(key);
69
- /* Listen events and return the result */
70
- return events.pipe(map(() => {
71
- if ((request.result !== undefined) && (request.result !== null)) {
72
- /* Prior to v8, the value was wrapped in an `{ value: ...}` object */
73
- if (!this.noWrap && (typeof request.result === 'object') && (this.wrapIndex in request.result) &&
74
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
75
- (request.result[this.wrapIndex] !== undefined) && (request.result[this.wrapIndex] !== null)) {
76
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
77
- return request.result[this.wrapIndex];
78
- }
79
- else {
80
- /* Cast to the wanted type */
81
- return request.result;
82
- }
83
- }
84
- /* Return `undefined` if the value is empty */
85
- return undefined;
86
- }));
87
- }),
88
- /* The observable will complete after the first value */
89
- first());
90
- }
91
- /**
92
- * Sets an item in our `indexedDB` store
93
- * @param key The item's key
94
- * @param data The item's value
95
- * @returns An RxJS `Observable` to wait the end of the operation
96
- */
97
- set(key, data) {
98
- /* Storing `undefined` in `indexedDb` can cause issues in some browsers so removing item instead */
99
- if (data === undefined) {
100
- return this.delete(key);
101
- }
102
- /* Open a transaction in write mode */
103
- return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
104
- const { store, events } = transactionData;
105
- /* Prior to v8, data was wrapped in a `{ value: ... }` object */
106
- const dataToStore = this.noWrap ? data : { [this.wrapIndex]: data };
107
- /* Add if the item is not existing yet, or update otherwise */
108
- store.put(dataToStore, key);
109
- /* Listen to events and return `undefined` as no value is expected */
110
- return events.pipe(mapTo(undefined));
111
- }),
112
- /* The observable will complete after the first value */
113
- first());
114
- }
115
- /**
116
- * Deletes an item in our `indexedDB` store
117
- * @param key The item's key
118
- * @returns An RxJS `Observable` to wait the end of the operation
119
- */
120
- delete(key) {
121
- /* Open a transaction in write mode */
122
- return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
123
- const { store, events } = transactionData;
124
- /* Delete the item in store */
125
- store.delete(key);
126
- /* Listen to events and return `undefined` as no data is expected here */
127
- return events.pipe(mapTo(undefined));
128
- }),
129
- /* The observable will complete after the first value */
130
- first());
131
- }
132
- /**
133
- * Deletes all items from our `indexedDB` objet store
134
- * @returns An RxJS `Observable` to wait the end of the operation
135
- */
136
- clear() {
137
- /* Open a transaction in write mode */
138
- return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
139
- const { store, events } = transactionData;
140
- /* Delete all items in object store */
141
- store.clear();
142
- /* Listen to events and return `undefined` as no data is expected here */
143
- return events.pipe(mapTo(undefined));
144
- }),
145
- /* The observable will complete */
146
- first());
147
- }
148
- /**
149
- * Get all the keys in our `indexedDB` store
150
- * @returns An RxJS `Observable` iterating on each key
151
- */
152
- keys() {
153
- /* Open a transaction in read-only mode */
154
- return this.transaction('readonly').pipe(
155
- /* `first()` is used as the final operator in other methods to complete the `Observable`
156
- * (as it all starts from a `ReplaySubject` which never ends),
157
- * but as this method is iterating over multiple values, `first()` **must** be used here */
158
- first(), mergeMap((transactionData) => {
159
- const { store } = transactionData;
160
- /* Open a cursor on the store
161
- * `.openKeyCursor()` is better for performance, but only available in indexedDB v2 (missing in IE)
162
- * Avoid issues like https://github.com/cyrilletuzi/angular-async-local-storage/issues/69 */
163
- const request = ('openKeyCursor' in store) ? store.openKeyCursor() : store.openCursor();
164
- /* Listen to success event */
165
- const success$ = fromEvent(request, 'success').pipe(
166
- /* Stop the `Observable` when the cursor is `null` */
167
- takeWhile(() => (request.result !== null)),
168
- /* This lib only allows string keys, but user could have added other types of keys from outside
169
- * It's OK to cast as the cursor as been tested in the previous operator */
170
- map(() => request.result.key.toString()),
171
- /* Iterate on the cursor */
172
- tap(() => { request.result.continue(); }));
173
- /* Listen to error event and if so, throw an error */
174
- const error$ = this.listenError(request);
175
- /* Choose the first event to occur */
176
- return race([success$, error$]);
177
- }));
178
- }
179
- /**
180
- * Check if a key exists in our `indexedDB` store
181
- * @returns An RxJS `Observable` telling if the key exists or not
182
- */
183
- has(key) {
184
- /* Open a transaction in read-only mode */
185
- return this.transaction('readonly').pipe(mergeMap((transactionData) => {
186
- const { store, events } = transactionData;
187
- /* Check if the key exists in the store
188
- * `getKey()` is better but only available in `indexedDB` v2 (Chrome >= 58, missing in IE/Edge Legacy).
189
- * In older browsers, the value is checked instead, but it could lead to an exception
190
- * if `undefined` was stored outside of this lib (e.g. directly with the native `indexedDB` API).
191
- * Fixes https://github.com/cyrilletuzi/angular-async-local-storage/issues/69
192
- */
193
- const request = ('getKey' in store) ? store.getKey(key) : store.get(key);
194
- /* Listen to events and return `true` or `false` */
195
- return events.pipe(map(() => (request.result !== undefined) ? true : false));
196
- }),
197
- /* The observable will complete */
198
- first());
199
- }
200
- /**
201
- * Connects to `indexedDB` and creates the object store on first time
202
- */
203
- connect() {
204
- let request;
205
- /* Connect to `indexedDB`
206
- * Will fail in Safari cross-origin iframes
207
- * @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/42} */
208
- try {
209
- /* Do NOT explicit `window` here, as `indexedDB` could be used from a web worker too */
210
- request = indexedDB.open(this.dbName, this.dbVersion);
211
- }
212
- catch (_a) {
213
- this.database.error(new IDBBrokenError());
214
- return;
215
- }
216
- /* Create store on first connection */
217
- this.createStore(request);
218
- /* Listen to success and error events */
219
- const success$ = fromEvent(request, 'success');
220
- const error$ = this.listenError(request);
221
- /* Choose the first to occur */
222
- race([success$, error$])
223
- /* The observable will complete */
224
- .pipe(first())
225
- .subscribe({
226
- next: () => {
227
- /* Register the database connection in the `ReplaySubject` for further access */
228
- this.database.next(request.result);
229
- },
230
- error: () => {
231
- /* Firefox private mode issue: fallback storage if IndexedDb connection is failing
232
- * @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=781982}
233
- * @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/26} */
234
- this.database.error(new IDBBrokenError());
235
- },
236
- });
237
- }
238
- /**
239
- * Create store on first use of `indexedDB`
240
- * @param request `indexedDB` database opening request
241
- */
242
- createStore(request) {
243
- /* Listen to the event fired on first connection */
244
- fromEvent(request, 'upgradeneeded')
245
- /* The observable will complete */
246
- .pipe(first())
247
- .subscribe({
248
- next: () => {
249
- /* Check if the store already exists, to avoid error */
250
- if (!request.result.objectStoreNames.contains(this.storeName)) {
251
- /* Create the object store */
252
- request.result.createObjectStore(this.storeName);
253
- }
254
- }
255
- });
256
- }
257
- /**
258
- * Open an `indexedDB` transaction and get our store
259
- * @param mode `readonly` or `readwrite`
260
- * @returns An `indexedDB` transaction store and events, wrapped in an RxJS `Observable`
261
- */
262
- transaction(mode) {
263
- /* From the `indexedDB` connection, open a transaction and get the store */
264
- return this.database
265
- .pipe(mergeMap((database) => {
266
- let transaction;
267
- try {
268
- transaction = database.transaction([this.storeName], mode);
269
- }
270
- catch (error) {
271
- /* The store could have been deleted from outside */
272
- return throwError(error);
273
- }
274
- /* Get the store from the transaction */
275
- const store = transaction.objectStore(this.storeName);
276
- /* Listen transaction `complete` and `error` events */
277
- const events = this.listenTransactionEvents(transaction);
278
- return of({ store, events });
279
- }));
280
- }
281
- /**
282
- * Listen errors on a transaction or request, and throw if trigerred
283
- * @param transactionOrRequest `indexedDb` transaction or request to listen
284
- * @returns An `Observable` listening to errors
285
- */
286
- listenError(transactionOrRequest) {
287
- return fromEvent(transactionOrRequest, 'error').pipe(
288
- /* Throw on error to be able to catch errors in RxJS way.
289
- * Here `event.target` must be used, as `transactionOrRequest.error` will be `null`
290
- * if we are on the request and the error is only triggered later by the transaction */
291
- mergeMap((event) => throwError(event.target.error)));
292
- }
293
- /**
294
- * Listen transaction `complete` and `error` events
295
- * @param transaction Transaction to listen
296
- * @returns An `Observable` listening to transaction `complete` and `error` events
297
- */
298
- listenTransactionEvents(transaction) {
299
- /* Listen to the `complete` event */
300
- const complete$ = fromEvent(transaction, 'complete');
301
- /* Listen to the `error` event */
302
- const error$ = this.listenError(transaction);
303
- /* Choose the first event to occur */
304
- return race([complete$, error$]);
305
- }
306
- }
307
- IndexedDBDatabase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.0", ngImport: i0, type: IndexedDBDatabase, deps: [{ token: IDB_DB_NAME }, { token: IDB_STORE_NAME }, { token: IDB_DB_VERSION }, { token: IDB_NO_WRAP }], target: i0.ɵɵFactoryTarget.Injectable });
308
- IndexedDBDatabase.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.0", ngImport: i0, type: IndexedDBDatabase, providedIn: 'root' });
309
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.0", ngImport: i0, type: IndexedDBDatabase, decorators: [{
310
- type: Injectable,
311
- args: [{
312
- providedIn: 'root'
313
- }]
314
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
315
- type: Inject,
316
- args: [IDB_DB_NAME]
317
- }] }, { type: undefined, decorators: [{
318
- type: Inject,
319
- args: [IDB_STORE_NAME]
320
- }] }, { type: undefined, decorators: [{
321
- type: Inject,
322
- args: [IDB_DB_VERSION]
323
- }] }, { type: undefined, decorators: [{
324
- type: Inject,
325
- args: [IDB_NO_WRAP]
326
- }] }]; } });
327
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXhlZGRiLWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXB3YS9sb2NhbC1zdG9yYWdlL3NyYy9saWIvZGF0YWJhc2VzL2luZGV4ZWRkYi1kYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWMsYUFBYSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsRixPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3RSxPQUFPLEVBQ0wsV0FBVyxFQUFFLGNBQWMsRUFBRSxzQkFBc0IsRUFBRSxjQUFjLEVBQ25FLG1CQUFtQixFQUFFLHNCQUFzQixFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFDOUUsTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7QUFNOUMsTUFBTSxPQUFPLGlCQUFpQjtJQWlDNUI7Ozs7OztPQU1HO0lBQ0gsWUFDdUIsTUFBTSxHQUFHLG1CQUFtQixFQUN6QixTQUFTLEdBQUcsc0JBQXNCLEVBQ2xDLFNBQVMsR0FBRyxzQkFBc0IsRUFDckMsTUFBTSxHQUFHLG1CQUFtQjtRQTNCbkQ7OztXQUdHO1FBQ2dCLGFBQVEsR0FBRyxJQUFJLGFBQWEsQ0FBYyxDQUFDLENBQUMsQ0FBQztRQU9oRTs7V0FFRztRQUNnQixjQUFTLEdBQUcsT0FBTyxDQUFDO1FBZ0JyQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENBQUMsU0FB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QyxLQUFLLENBQUMsQ0FBQyxDQUNyRixDQUFDO0lBRUosQ0FBQztJQUVEOzs7O09BSUc7SUFDTyx1QkFBdUIsQ0FBQyxXQUEyQjtRQUUzRCxvQ0FBb0M7UUFDcEMsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUVyRCxpQ0FBaUM7UUFDakMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUU3QyxxQ0FBcUM7UUFDckMsT0FBTyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUVuQyxDQUFDOzs4R0FsY1UsaUJBQWlCLGtCQXlDbEIsV0FBVyxhQUNYLGNBQWMsYUFDZCxjQUFjLGFBQ2QsV0FBVztrSEE1Q1YsaUJBQWlCLGNBRmhCLE1BQU07MkZBRVAsaUJBQWlCO2tCQUg3QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs7MEJBMENJLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLE1BQU07MkJBQUMsY0FBYzs7MEJBQ3JCLE1BQU07MkJBQUMsY0FBYzs7MEJBQ3JCLE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgUmVwbGF5U3ViamVjdCwgZnJvbUV2ZW50LCBvZiwgdGhyb3dFcnJvciwgcmFjZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCBtZXJnZU1hcCwgZmlyc3QsIHRha2VXaGlsZSwgdGFwLCBtYXBUbyB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgSURCX0RCX05BTUUsIElEQl9TVE9SRV9OQU1FLCBERUZBVUxUX0lEQl9TVE9SRV9OQU1FLCBJREJfREJfVkVSU0lPTixcbiAgREVGQVVMVF9JREJfREJfTkFNRSwgREVGQVVMVF9JREJfREJfVkVSU0lPTiwgSURCX05PX1dSQVAsIERFRkFVTFRfSURCX05PX1dSQVBcbn0gZnJvbSAnLi4vdG9rZW5zJztcbmltcG9ydCB7IElEQkJyb2tlbkVycm9yIH0gZnJvbSAnLi9leGNlcHRpb25zJztcbmltcG9ydCB7IExvY2FsRGF0YWJhc2UgfSBmcm9tICcuL2xvY2FsLWRhdGFiYXNlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgSW5kZXhlZERCRGF0YWJhc2UgaW1wbGVtZW50cyBMb2NhbERhdGFiYXNlIHtcblxuICAvKipcbiAgICogYGluZGV4ZWREQmAgZGF0YWJhc2UgbmFtZVxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRiTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBgaW5kZXhlZERCYCBvYmplY3Qgc3RvcmUgbmFtZVxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHN0b3JlTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBgaW5kZXhlZERCYCBkYXRhYmFzZSB2ZXJzaW9uLiBNdXN0IGJlIGFuIHVuc2lnbmVkICoqaW50ZWdlcioqXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGJWZXJzaW9uOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIGBpbmRleGVkREJgIGRhdGFiYXNlIGNvbm5lY3Rpb24sIHdyYXBwZWQgaW4gYSBSeEpTIGBSZXBsYXlTdWJqZWN0YCB0byBiZSBhYmxlIHRvIGFjY2VzcyB0aGUgY29ubmVjdGlvblxuICAgKiBldmVuIGFmdGVyIHRoZSBjb25uZWN0aW9uIHN1Y2Nlc3MgZXZlbnQgaGFwcGVuZWRcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBkYXRhYmFzZSA9IG5ldyBSZXBsYXlTdWJqZWN0PElEQkRhdGFiYXNlPigxKTtcblxuICAvKipcbiAgICogRmxhZyB0byBub3Qgd3JhcCBgaW5kZXhlZERCYCB2YWx1ZXMgZm9yIGludGVyb3BlcmFiaWxpdHkgb3IgdG8gd3JhcCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBub1dyYXA6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEluZGV4IHVzZWQgd2hlbiB3cmFwcGluZyB2YWx1ZS4gKkZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IG9ubHkuKlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHdyYXBJbmRleCA9ICd2YWx1ZSc7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIHBhcmFtcyBhcmUgcHJvdmlkZWQgYnkgQW5ndWxhciAoYnV0IGNhbiBhbHNvIGJlIHBhc3NlZCBtYW51YWxseSBpbiB0ZXN0cylcbiAgICogQHBhcmFtIGRiTmFtZSBgaW5kZXhlZERCYCBkYXRhYmFzZSBuYW1lXG4gICAqIEBwYXJhbSBzdG9yZU5hbWUgYGluZGV4ZWREQmAgc3RvcmUgbmFtZVxuICAgKiBAcGFyYW0gZGJWZXJzaW9uIGBpbmRleGVkREJgIGRhdGFiYXNlIHZlcnNpb25cbiAgICogQHBhcmFtIG5vV3JhcCBGbGFnIHRvIG5vdCB3cmFwIGBpbmRleGVkREJgIHZhbHVlcyBmb3IgaW50ZXJvcGVyYWJpbGl0eSBvciB0byB3cmFwIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KElEQl9EQl9OQU1FKSBkYk5hbWUgPSBERUZBVUxUX0lEQl9EQl9OQU1FLFxuICAgIEBJbmplY3QoSURCX1NUT1JFX05BTUUpIHN0b3JlTmFtZSA9IERFRkFVTFRfSURCX1NUT1JFX05BTUUsXG4gICAgQEluamVjdChJREJfREJfVkVSU0lPTikgZGJWZXJzaW9uID0gREVGQVVMVF9JREJfREJfVkVSU0lPTixcbiAgICBASW5qZWN0KElEQl9OT19XUkFQKSBub1dyYXAgPSBERUZBVUxUX0lEQl9OT19XUkFQLFxuICApIHtcblxuICAgIHRoaXMuZGJOYW1lID0gZGJOYW1lO1xuICAgIHRoaXMuc3RvcmVOYW1lID0gc3RvcmVOYW1lO1xuICAgIHRoaXMuZGJWZXJzaW9uID0gZGJWZXJzaW9uO1xuICAgIHRoaXMubm9XcmFwID0gbm9XcmFwO1xuXG4gICAgLyogQ29ubmVjdCB0byBgaW5kZXhlZERCYCwgd2l0aCBwcmVmaXggaWYgcHJvdmlkZWQgYnkgdGhlIHVzZXIgKi9cbiAgICB0aGlzLmNvbm5lY3QoKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEluZm9ybWF0aW9uIGFib3V0IGBpbmRleGVkREJgIGNvbm5lY3Rpb24uICpPbmx5IHVzZWZ1bCBmb3IgaW50ZXJvcGVyYWJpbGl0eS4qXG4gICAqIEByZXR1cm5zIGBpbmRleGVkREJgIGRhdGFiYXNlIG5hbWUsIHN0b3JlIG5hbWUgYW5kIGRhdGFiYXNlIHZlcnNpb25cbiAgICovXG4gIGdldCBiYWNraW5nU3RvcmUoKTogeyBkYXRhYmFzZTogc3RyaW5nLCBzdG9yZTogc3RyaW5nLCB2ZXJzaW9uOiBudW1iZXIgfSB7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YWJhc2U6IHRoaXMuZGJOYW1lLFxuICAgICAgc3RvcmU6IHRoaXMuc3RvcmVOYW1lLFxuICAgICAgdmVyc2lvbjogdGhpcy5kYlZlcnNpb24sXG4gICAgfTtcblxuICB9XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBpdGVtcyBpbiBvdXIgYGluZGV4ZWREQmAgZGF0YWJhc2UgYW5kIG9iamVjdCBzdG9yZVxuICAgKi9cbiAgZ2V0IHNpemUoKTogT2JzZXJ2YWJsZTxudW1iZXI+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogUmVxdWVzdCB0byBrbm93IHRoZSBudW1iZXIgb2YgaXRlbXMgKi9cbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmNvdW50KCk7XG5cbiAgICAgICAgLyogUmV0dXJuIHRoZSByZXN1bHQgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcCgoKSA9PiByZXF1ZXN0LnJlc3VsdCkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgYWZ0ZXIgdGhlIGZpcnN0IHZhbHVlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFuIGl0ZW0gdmFsdWUgaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgVGhlIGl0ZW0ncyB2YWx1ZSBpZiB0aGUga2V5IGV4aXN0cywgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLCB3cmFwcGVkIGluIGFuIFJ4SlMgYE9ic2VydmFibGVgXG4gICAqL1xuICBnZXQoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHVua25vd24gfCB1bmRlZmluZWQ+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogUmVxdWVzdCB0aGUgdmFsdWUgd2l0aCB0aGUga2V5IHByb3ZpZGVkIGJ5IHRoZSB1c2VyICovXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5nZXQoa2V5KTtcblxuICAgICAgICAvKiBMaXN0ZW4gZXZlbnRzIGFuZCByZXR1cm4gdGhlIHJlc3VsdCAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwKCgpOiB1bmtub3duID0+IHtcblxuICAgICAgICAgIGlmICgocmVxdWVzdC5yZXN1bHQgIT09IHVuZGVmaW5lZCkgJiYgKHJlcXVlc3QucmVzdWx0ICE9PSBudWxsKSkge1xuXG4gICAgICAgICAgICAvKiBQcmlvciB0byB2OCwgdGhlIHZhbHVlIHdhcyB3cmFwcGVkIGluIGFuIGB7IHZhbHVlOiAuLi59YCBvYmplY3QgKi9cbiAgICAgICAgICAgIGlmICghdGhpcy5ub1dyYXAgJiYgKHR5cGVvZiByZXF1ZXN0LnJlc3VsdCA9PT0gJ29iamVjdCcpICYmICh0aGlzLndyYXBJbmRleCBpbiByZXF1ZXN0LnJlc3VsdCkgJiZcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3NcbiAgICAgICAgICAgIChyZXF1ZXN0LnJlc3VsdFt0aGlzLndyYXBJbmRleF0gIT09IHVuZGVmaW5lZCkgJiYgKHJlcXVlc3QucmVzdWx0W3RoaXMud3JhcEluZGV4XSAhPT0gbnVsbCkpIHtcblxuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzXG4gICAgICAgICAgICAgIHJldHVybiByZXF1ZXN0LnJlc3VsdFt0aGlzLndyYXBJbmRleF07XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgLyogQ2FzdCB0byB0aGUgd2FudGVkIHR5cGUgKi9cbiAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QucmVzdWx0O1xuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvKiBSZXR1cm4gYHVuZGVmaW5lZGAgaWYgdGhlIHZhbHVlIGlzIGVtcHR5ICovXG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICB9KSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgdmFsdWUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYW4gaXRlbSBpbiBvdXIgYGluZGV4ZWREQmAgc3RvcmVcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gZGF0YSBUaGUgaXRlbSdzIHZhbHVlXG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqL1xuICBzZXQoa2V5OiBzdHJpbmcsIGRhdGE6IHVua25vd24pOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgLyogU3RvcmluZyBgdW5kZWZpbmVkYCBpbiBgaW5kZXhlZERiYCBjYW4gY2F1c2UgaXNzdWVzIGluIHNvbWUgYnJvd3NlcnMgc28gcmVtb3ZpbmcgaXRlbSBpbnN0ZWFkICovXG4gICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlKGtleSk7XG4gICAgfVxuXG4gICAgLyogT3BlbiBhIHRyYW5zYWN0aW9uIGluIHdyaXRlIG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZHdyaXRlJykucGlwZShcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlLCBldmVudHMgfSA9IHRyYW5zYWN0aW9uRGF0YTtcblxuICAgICAgICAvKiBQcmlvciB0byB2OCwgZGF0YSB3YXMgd3JhcHBlZCBpbiBhIGB7IHZhbHVlOiAuLi4gfWAgb2JqZWN0ICovXG4gICAgICAgIGNvbnN0IGRhdGFUb1N0b3JlID0gdGhpcy5ub1dyYXAgPyBkYXRhIDogeyBbdGhpcy53cmFwSW5kZXhdOiBkYXRhIH07XG5cbiAgICAgICAgLyogQWRkIGlmIHRoZSBpdGVtIGlzIG5vdCBleGlzdGluZyB5ZXQsIG9yIHVwZGF0ZSBvdGhlcndpc2UgKi9cbiAgICAgICAgc3RvcmUucHV0KGRhdGFUb1N0b3JlLCBrZXkpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBldmVudHMgYW5kIHJldHVybiBgdW5kZWZpbmVkYCBhcyBubyB2YWx1ZSBpcyBleHBlY3RlZCAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwVG8odW5kZWZpbmVkKSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgdmFsdWUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYW4gaXRlbSBpbiBvdXIgYGluZGV4ZWREQmAgc3RvcmVcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcmV0dXJucyBBbiBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiB3cml0ZSBtb2RlICovXG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb24oJ3JlYWR3cml0ZScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogRGVsZXRlIHRoZSBpdGVtIGluIHN0b3JlICovXG4gICAgICAgIHN0b3JlLmRlbGV0ZShrZXkpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBldmVudHMgYW5kIHJldHVybiBgdW5kZWZpbmVkYCBhcyBubyBkYXRhIGlzIGV4cGVjdGVkIGhlcmUgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcFRvKHVuZGVmaW5lZCkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgYWZ0ZXIgdGhlIGZpcnN0IHZhbHVlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFsbCBpdGVtcyBmcm9tIG91ciBgaW5kZXhlZERCYCBvYmpldCBzdG9yZVxuICAgKiBAcmV0dXJucyBBbiBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgY2xlYXIoKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiB3cml0ZSBtb2RlICovXG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb24oJ3JlYWR3cml0ZScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogRGVsZXRlIGFsbCBpdGVtcyBpbiBvYmplY3Qgc3RvcmUgKi9cbiAgICAgICAgc3RvcmUuY2xlYXIoKTtcblxuICAgICAgICAvKiBMaXN0ZW4gdG8gZXZlbnRzIGFuZCByZXR1cm4gYHVuZGVmaW5lZGAgYXMgbm8gZGF0YSBpcyBleHBlY3RlZCBoZXJlICovXG4gICAgICAgIHJldHVybiBldmVudHMucGlwZShtYXBUbyh1bmRlZmluZWQpKTtcblxuICAgICAgfSksXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIHRoZSBrZXlzIGluIG91ciBgaW5kZXhlZERCYCBzdG9yZVxuICAgKiBAcmV0dXJucyBBbiBSeEpTIGBPYnNlcnZhYmxlYCBpdGVyYXRpbmcgb24gZWFjaCBrZXlcbiAgICovXG4gIGtleXMoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICAvKiBgZmlyc3QoKWAgaXMgdXNlZCBhcyB0aGUgZmluYWwgb3BlcmF0b3IgaW4gb3RoZXIgbWV0aG9kcyB0byBjb21wbGV0ZSB0aGUgYE9ic2VydmFibGVgXG4gICAgICAgKiAoYXMgaXQgYWxsIHN0YXJ0cyBmcm9tIGEgYFJlcGxheVN1YmplY3RgIHdoaWNoIG5ldmVyIGVuZHMpLFxuICAgICAgICogYnV0IGFzIHRoaXMgbWV0aG9kIGlzIGl0ZXJhdGluZyBvdmVyIG11bHRpcGxlIHZhbHVlcywgYGZpcnN0KClgICoqbXVzdCoqIGJlIHVzZWQgaGVyZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogT3BlbiBhIGN1cnNvciBvbiB0aGUgc3RvcmVcbiAgICAgICAgICogYC5vcGVuS2V5Q3Vyc29yKClgIGlzIGJldHRlciBmb3IgcGVyZm9ybWFuY2UsIGJ1dCBvbmx5IGF2YWlsYWJsZSBpbiBpbmRleGVkREIgdjIgKG1pc3NpbmcgaW4gSUUpXG4gICAgICAgICAqIEF2b2lkIGlzc3VlcyBsaWtlIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzY5ICovXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSAoJ29wZW5LZXlDdXJzb3InIGluIHN0b3JlKSA/IHN0b3JlLm9wZW5LZXlDdXJzb3IoKSA6IChzdG9yZSBhcyBJREJPYmplY3RTdG9yZSkub3BlbkN1cnNvcigpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBzdWNjZXNzIGV2ZW50ICovXG4gICAgICAgIGNvbnN0IHN1Y2Nlc3MkID0gZnJvbUV2ZW50KHJlcXVlc3QsICdzdWNjZXNzJykucGlwZShcbiAgICAgICAgICAvKiBTdG9wIHRoZSBgT2JzZXJ2YWJsZWAgd2hlbiB0aGUgY3Vyc29yIGlzIGBudWxsYCAqL1xuICAgICAgICAgIHRha2VXaGlsZSgoKSA9PiAocmVxdWVzdC5yZXN1bHQgIT09IG51bGwpKSxcbiAgICAgICAgICAvKiBUaGlzIGxpYiBvbmx5IGFsbG93cyBzdHJpbmcga2V5cywgYnV0IHVzZXIgY291bGQgaGF2ZSBhZGRlZCBvdGhlciB0eXBlcyBvZiBrZXlzIGZyb20gb3V0c2lkZVxuICAgICAgICAgICAqIEl0J3MgT0sgdG8gY2FzdCBhcyB0aGUgY3Vyc29yIGFzIGJlZW4gdGVzdGVkIGluIHRoZSBwcmV2aW91cyBvcGVyYXRvciAqL1xuICAgICAgICAgIG1hcCgoKSA9PiAocmVxdWVzdC5yZXN1bHQgYXMgSURCQ3Vyc29yKS5rZXkudG9TdHJpbmcoKSksXG4gICAgICAgICAgLyogSXRlcmF0ZSBvbiB0aGUgY3Vyc29yICovXG4gICAgICAgICAgdGFwKCgpID0+IHsgKHJlcXVlc3QucmVzdWx0IGFzIElEQkN1cnNvcikuY29udGludWUoKTsgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgLyogTGlzdGVuIHRvIGVycm9yIGV2ZW50IGFuZCBpZiBzbywgdGhyb3cgYW4gZXJyb3IgKi9cbiAgICAgICAgY29uc3QgZXJyb3IkID0gdGhpcy5saXN0ZW5FcnJvcihyZXF1ZXN0KTtcblxuICAgICAgICAvKiBDaG9vc2UgdGhlIGZpcnN0IGV2ZW50IHRvIG9jY3VyICovXG4gICAgICAgIHJldHVybiByYWNlKFtzdWNjZXNzJCwgZXJyb3IkXSk7XG5cbiAgICAgIH0pLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGtleSBleGlzdHMgaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIHRlbGxpbmcgaWYgdGhlIGtleSBleGlzdHMgb3Igbm90XG4gICAqL1xuICBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogQ2hlY2sgaWYgdGhlIGtleSBleGlzdHMgaW4gdGhlIHN0b3JlXG4gICAgICAgICAqIGBnZXRLZXkoKWAgaXMgYmV0dGVyIGJ1dCBvbmx5IGF2YWlsYWJsZSBpbiBgaW5kZXhlZERCYCB2MiAoQ2hyb21lID49IDU4LCBtaXNzaW5nIGluIElFL0VkZ2UgTGVnYWN5KS5cbiAgICAgICAgICogSW4gb2xkZXIgYnJvd3NlcnMsIHRoZSB2YWx1ZSBpcyBjaGVja2VkIGluc3RlYWQsIGJ1dCBpdCBjb3VsZCBsZWFkIHRvIGFuIGV4Y2VwdGlvblxuICAgICAgICAgKiBpZiBgdW5kZWZpbmVkYCB3YXMgc3RvcmVkIG91dHNpZGUgb2YgdGhpcyBsaWIgKGUuZy4gZGlyZWN0bHkgd2l0aCB0aGUgbmF0aXZlIGBpbmRleGVkREJgIEFQSSkuXG4gICAgICAgICAqIEZpeGVzIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzY5XG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gICgnZ2V0S2V5JyBpbiBzdG9yZSkgPyBzdG9yZS5nZXRLZXkoa2V5KSA6IChzdG9yZSBhcyBJREJPYmplY3RTdG9yZSkuZ2V0KGtleSk7XG5cbiAgICAgICAgLyogTGlzdGVuIHRvIGV2ZW50cyBhbmQgcmV0dXJuIGB0cnVlYCBvciBgZmFsc2VgICovXG4gICAgICAgIHJldHVybiBldmVudHMucGlwZShtYXAoKCkgPT4gKHJlcXVlc3QucmVzdWx0ICE9PSB1bmRlZmluZWQpID8gdHJ1ZSA6IGZhbHNlKSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogQ29ubmVjdHMgdG8gYGluZGV4ZWREQmAgYW5kIGNyZWF0ZXMgdGhlIG9iamVjdCBzdG9yZSBvbiBmaXJzdCB0aW1lXG4gICAqL1xuICBwcm90ZWN0ZWQgY29ubmVjdCgpOiB2b2lkIHtcblxuICAgIGxldCByZXF1ZXN0OiBJREJPcGVuREJSZXF1ZXN0O1xuXG4gICAgLyogQ29ubmVjdCB0byBgaW5kZXhlZERCYFxuICAgICAqIFdpbGwgZmFpbCBpbiBTYWZhcmkgY3Jvc3Mtb3JpZ2luIGlmcmFtZXNcbiAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy80Mn0gKi9cbiAgICB0cnkge1xuXG4gICAgICAvKiBEbyBOT1QgZXhwbGljaXQgYHdpbmRvd2AgaGVyZSwgYXMgYGluZGV4ZWREQmAgY291bGQgYmUgdXNlZCBmcm9tIGEgd2ViIHdvcmtlciB0b28gKi9cbiAgICAgIHJlcXVlc3QgPSBpbmRleGVkREIub3Blbih0aGlzLmRiTmFtZSwgdGhpcy5kYlZlcnNpb24pO1xuXG4gICAgfSBjYXRjaCB7XG5cbiAgICAgIHRoaXMuZGF0YWJhc2UuZXJyb3IobmV3IElEQkJyb2tlbkVycm9yKCkpO1xuXG4gICAgICByZXR1cm47XG5cbiAgICB9XG5cbiAgICAvKiBDcmVhdGUgc3RvcmUgb24gZmlyc3QgY29ubmVjdGlvbiAqL1xuICAgIHRoaXMuY3JlYXRlU3RvcmUocmVxdWVzdCk7XG5cbiAgICAvKiBMaXN0ZW4gdG8gc3VjY2VzcyBhbmQgZXJyb3IgZXZlbnRzICovXG4gICAgY29uc3Qgc3VjY2VzcyQgPSBmcm9tRXZlbnQocmVxdWVzdCwgJ3N1Y2Nlc3MnKTtcbiAgICBjb25zdCBlcnJvciQgPSB0aGlzLmxpc3RlbkVycm9yKHJlcXVlc3QpO1xuXG4gICAgLyogQ2hvb3NlIHRoZSBmaXJzdCB0byBvY2N1ciAqL1xuICAgIHJhY2UoW3N1Y2Nlc3MkLCBlcnJvciRdKVxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSAqL1xuICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoKSA9PiB7XG4gICAgICAgICAgLyogUmVnaXN0ZXIgdGhlIGRhdGFiYXNlIGNvbm5lY3Rpb24gaW4gdGhlIGBSZXBsYXlTdWJqZWN0YCBmb3IgZnVydGhlciBhY2Nlc3MgKi9cbiAgICAgICAgICB0aGlzLmRhdGFiYXNlLm5leHQocmVxdWVzdC5yZXN1bHQpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgIC8qIEZpcmVmb3ggcHJpdmF0ZSBtb2RlIGlzc3VlOiBmYWxsYmFjayBzdG9yYWdlIGlmIEluZGV4ZWREYiBjb25uZWN0aW9uIGlzIGZhaWxpbmdcbiAgICAgICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTc4MTk4Mn1cbiAgICAgICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzI2fSAqL1xuICAgICAgICAgIHRoaXMuZGF0YWJhc2UuZXJyb3IobmV3IElEQkJyb2tlbkVycm9yKCkpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgc3RvcmUgb24gZmlyc3QgdXNlIG9mIGBpbmRleGVkREJgXG4gICAqIEBwYXJhbSByZXF1ZXN0IGBpbmRleGVkREJgIGRhdGFiYXNlIG9wZW5pbmcgcmVxdWVzdFxuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZVN0b3JlKHJlcXVlc3Q6IElEQk9wZW5EQlJlcXVlc3QpOiB2b2lkIHtcblxuICAgIC8qIExpc3RlbiB0byB0aGUgZXZlbnQgZmlyZWQgb24gZmlyc3QgY29ubmVjdGlvbiAqL1xuICAgIGZyb21FdmVudChyZXF1ZXN0LCAndXBncmFkZW5lZWRlZCcpXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlICovXG4gICAgICAucGlwZShmaXJzdCgpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICgpID0+IHtcblxuICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSBzdG9yZSBhbHJlYWR5IGV4aXN0cywgdG8gYXZvaWQgZXJyb3IgKi9cbiAgICAgICAgICBpZiAoIXJlcXVlc3QucmVzdWx0Lm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnModGhpcy5zdG9yZU5hbWUpKSB7XG5cbiAgICAgICAgICAgIC8qIENyZWF0ZSB0aGUgb2JqZWN0IHN0b3JlICovXG4gICAgICAgICAgICByZXF1ZXN0LnJlc3VsdC5jcmVhdGVPYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVuIGFuIGBpbmRleGVkREJgIHRyYW5zYWN0aW9uIGFuZCBnZXQgb3VyIHN0b3JlXG4gICAqIEBwYXJhbSBtb2RlIGByZWFkb25seWAgb3IgYHJlYWR3cml0ZWBcbiAgICogQHJldHVybnMgQW4gYGluZGV4ZWREQmAgdHJhbnNhY3Rpb24gc3RvcmUgYW5kIGV2ZW50cywgd3JhcHBlZCBpbiBhbiBSeEpTIGBPYnNlcnZhYmxlYFxuICAgKi9cbiAgcHJvdGVjdGVkIHRyYW5zYWN0aW9uKG1vZGU6IElEQlRyYW5zYWN0aW9uTW9kZSk6IE9ic2VydmFibGU8e1xuICAgIHN0b3JlOiBJREJPYmplY3RTdG9yZTtcbiAgICBldmVudHM6IE9ic2VydmFibGU8RXZlbnQ+O1xuICB9PiB7XG5cbiAgICAvKiBGcm9tIHRoZSBgaW5kZXhlZERCYCBjb25uZWN0aW9uLCBvcGVuIGEgdHJhbnNhY3Rpb24gYW5kIGdldCB0aGUgc3RvcmUgKi9cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZVxuICAgICAgLnBpcGUobWVyZ2VNYXAoKGRhdGFiYXNlKSA9PiB7XG5cbiAgICAgICAgbGV0IHRyYW5zYWN0aW9uOiBJREJUcmFuc2FjdGlvbjtcblxuICAgICAgICB0cnkge1xuXG4gICAgICAgICAgdHJhbnNhY3Rpb24gPSBkYXRhYmFzZS50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCBtb2RlKTtcblxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuXG4gICAgICAgICAgICAvKiBUaGUgc3RvcmUgY291bGQgaGF2ZSBiZWVuIGRlbGV0ZWQgZnJvbSBvdXRzaWRlICovXG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvciBhcyBET01FeGNlcHRpb24pO1xuXG4gICAgICAgIH1cblxuICAgICAgICAvKiBHZXQgdGhlIHN0b3JlIGZyb20gdGhlIHRyYW5zYWN0aW9uICovXG4gICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0cmFuc2FjdGlvbiBgY29tcGxldGVgIGFuZCBgZXJyb3JgIGV2ZW50cyAqL1xuICAgICAgICBjb25zdCBldmVudHMgPSB0aGlzLmxpc3RlblRyYW5zYWN0aW9uRXZlbnRzKHRyYW5zYWN0aW9uKTtcblxuICAgICAgICByZXR1cm4gb2YoeyBzdG9yZSwgZXZlbnRzIH0pO1xuXG4gICAgICB9KSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0ZW4gZXJyb3JzIG9uIGEgdHJhbnNhY3Rpb24gb3IgcmVxdWVzdCwgYW5kIHRocm93IGlmIHRyaWdlcnJlZFxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25PclJlcXVlc3QgYGluZGV4ZWREYmAgdHJhbnNhY3Rpb24gb3IgcmVxdWVzdCB0byBsaXN0ZW5cbiAgICogQHJldHVybnMgQW4gYE9ic2VydmFibGVgIGxpc3RlbmluZyB0byBlcnJvcnNcbiAgICovXG4gIHByb3RlY3RlZCBsaXN0ZW5FcnJvcih0cmFuc2FjdGlvbk9yUmVxdWVzdDogSURCVHJhbnNhY3Rpb24gfCBJREJSZXF1ZXN0KTogT2JzZXJ2YWJsZTxuZXZlcj4ge1xuXG4gICAgcmV0dXJuIGZyb21FdmVudCh0cmFuc2FjdGlvbk9yUmVxdWVzdCwgJ2Vycm9yJykucGlwZShcbiAgICAgIC8qIFRocm93IG9uIGVycm9yIHRvIGJlIGFibGUgdG8gY2F0Y2ggZXJyb3JzIGluIFJ4SlMgd2F5LlxuICAgICAgICogSGVyZSBgZXZlbnQudGFyZ2V0YCBtdXN0IGJlIHVzZWQsIGFzIGB0cmFuc2FjdGlvbk9yUmVxdWVzdC5lcnJvcmAgd2lsbCBiZSBgbnVsbGBcbiAgICAgICAqIGlmIHdlIGFyZSBvbiB0aGUgcmVxdWVzdCBhbmQgdGhlIGVycm9yIGlzIG9ubHkgdHJpZ2dlcmVkIGxhdGVyIGJ5IHRoZSB0cmFuc2FjdGlvbiAqL1xuICAgICAgbWVyZ2VNYXAoKGV2ZW50KSA9PiB0aHJvd0Vycm9yKChldmVudC50YXJnZXQgYXMgSURCVHJhbnNhY3Rpb24gfCBJREJSZXF1ZXN0KS5lcnJvcikpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0ZW4gdHJhbnNhY3Rpb24gYGNvbXBsZXRlYCBhbmQgYGVycm9yYCBldmVudHNcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uIFRyYW5zYWN0aW9uIHRvIGxpc3RlblxuICAgKiBAcmV0dXJucyBBbiBgT2JzZXJ2YWJsZWAgbGlzdGVuaW5nIHRvIHRyYW5zYWN0aW9uIGBjb21wbGV0ZWAgYW5kIGBlcnJvcmAgZXZlbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgbGlzdGVuVHJhbnNhY3Rpb25FdmVudHModHJhbnNhY3Rpb246IElEQlRyYW5zYWN0aW9uKTogT2JzZXJ2YWJsZTxFdmVudD4ge1xuXG4gICAgLyogTGlzdGVuIHRvIHRoZSBgY29tcGxldGVgIGV2ZW50ICovXG4gICAgY29uc3QgY29tcGxldGUkID0gZnJvbUV2ZW50KHRyYW5zYWN0aW9uLCAnY29tcGxldGUnKTtcblxuICAgIC8qIExpc3RlbiB0byB0aGUgYGVycm9yYCBldmVudCAqL1xuICAgIGNvbnN0IGVycm9yJCA9IHRoaXMubGlzdGVuRXJyb3IodHJhbnNhY3Rpb24pO1xuXG4gICAgLyogQ2hvb3NlIHRoZSBmaXJzdCBldmVudCB0byBvY2N1ciAqL1xuICAgIHJldHVybiByYWNlKFtjb21wbGV0ZSQsIGVycm9yJF0pO1xuXG4gIH1cblxufVxuIl19
@@ -1,80 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { mapTo, map } from 'rxjs/operators';
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "./storage-map.service";
5
- export class LocalStorage {
6
- /* Use the `StorageMap` service to avoid code duplication */
7
- constructor(storageMap) {
8
- this.storageMap = storageMap;
9
- }
10
- /**
11
- * Number of items in storage wrapped in an `Observable`
12
- *
13
- * @example
14
- * this.localStorage.length.subscribe((length) => {
15
- * console.log(length);
16
- * });
17
- */
18
- get length() {
19
- return this.storageMap.size;
20
- }
21
- getItem(key, schema) {
22
- if (schema) {
23
- /* Backward compatibility with version <= 7 */
24
- schema = ('schema' in schema) ? schema.schema : schema;
25
- }
26
- return (schema ? this.storageMap.get(key, schema) : this.storageMap.get(key)).pipe(
27
- /* Transform `undefined` into `null` to align with `localStorage` API */
28
- map((value) => (value !== undefined) ? value : null));
29
- }
30
- /**
31
- * Set an item in storage.
32
- * Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
33
- * @param key The item's key
34
- * @param data The item's value
35
- * @param schema Optional JSON schema to validate the data
36
- * @returns A RxJS `Observable` to wait the end of the operation
37
- *
38
- * @example
39
- * this.localStorage.set('key', 'value').subscribe(() => {});
40
- */
41
- setItem(key, data, schema) {
42
- return this.storageMap.set(key, data, schema).pipe(
43
- /* Transform `undefined` into `true` for backward compatibility with v7 */
44
- mapTo(true));
45
- }
46
- /**
47
- * Delete an item in storage
48
- * @param key The item's key
49
- * @returns A RxJS `Observable` to wait the end of the operation
50
- *
51
- * @example
52
- * this.localStorage.delete('key').subscribe(() => {});
53
- */
54
- removeItem(key) {
55
- return this.storageMap.delete(key).pipe(
56
- /* Transform `undefined` into `true` for backward compatibility with v7 */
57
- mapTo(true));
58
- }
59
- /**
60
- * Delete all items in storage
61
- * @returns A RxJS `Observable` to wait the end of the operation
62
- *
63
- * @example
64
- * this.localStorage.clear().subscribe(() => {});
65
- */
66
- clear() {
67
- return this.storageMap.clear().pipe(
68
- /* Transform `undefined` into `true` for backward compatibility with v7 */
69
- mapTo(true));
70
- }
71
- }
72
- LocalStorage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.0", ngImport: i0, type: LocalStorage, deps: [{ token: i1.StorageMap }], target: i0.ɵɵFactoryTarget.Injectable });
73
- LocalStorage.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.0", ngImport: i0, type: LocalStorage, providedIn: 'root' });
74
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.0", ngImport: i0, type: LocalStorage, decorators: [{
75
- type: Injectable,
76
- args: [{
77
- providedIn: 'root'
78
- }]
79
- }], ctorParameters: function () { return [{ type: i1.StorageMap }]; } });
80
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtc3RvcmFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXB3YS9sb2NhbC1zdG9yYWdlL3NyYy9saWIvc3RvcmFnZXMvbG9jYWwtc3RvcmFnZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBVzVDLE1BQU0sT0FBTyxZQUFZO0lBZ0J2Qiw0REFBNEQ7SUFDNUQsWUFBc0IsVUFBc0I7UUFBdEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtJQUFHLENBQUM7SUFmaEQ7Ozs7Ozs7T0FPRztJQUNILElBQUksTUFBTTtRQUVSLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFFOUIsQ0FBQztJQWtERCxPQUFPLENBQWMsR0FBVyxFQUFFLE1BQXdEO1FBRXhGLElBQUksTUFBTSxFQUFFO1lBRVYsOENBQThDO1lBQzlDLE1BQU0sR0FBRyxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1NBRXhEO1FBRUQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUksR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUk7UUFDbkYsd0VBQXdFO1FBQ3hFLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQ3JELENBQUM7SUFFSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNILE9BQU8sQ0FBQyxHQUFXLEVBQUUsSUFBYSxFQUFFLE1BQW1CO1FBRXJELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxJQUFJO1FBQ2hELDBFQUEwRTtRQUMxRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQ1osQ0FBQztJQUVKLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsVUFBVSxDQUFDLEdBQVc7UUFFcEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJO1FBQ3JDLDBFQUEwRTtRQUMxRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQ1osQ0FBQztJQUVKLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLO1FBRUgsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUk7UUFDakMsMEVBQTBFO1FBQzFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FDWixDQUFDO0lBRUosQ0FBQzs7eUdBbklVLFlBQVk7NkdBQVosWUFBWSxjQUZYLE1BQU07MkZBRVAsWUFBWTtrQkFIeEIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXBUbywgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge1xuICBKU09OU2NoZW1hLCBKU09OU2NoZW1hQm9vbGVhbiwgSlNPTlNjaGVtYUludGVnZXIsXG4gIEpTT05TY2hlbWFOdW1iZXIsIEpTT05TY2hlbWFTdHJpbmcsIEpTT05TY2hlbWFBcnJheU9mXG59IGZyb20gJy4uL3ZhbGlkYXRpb24vanNvbi1zY2hlbWEnO1xuaW1wb3J0IHsgU3RvcmFnZU1hcCB9IGZyb20gJy4vc3RvcmFnZS1tYXAuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIExvY2FsU3RvcmFnZSB7XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBpdGVtcyBpbiBzdG9yYWdlIHdyYXBwZWQgaW4gYW4gYE9ic2VydmFibGVgXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLmxlbmd0aC5zdWJzY3JpYmUoKGxlbmd0aCkgPT4ge1xuICAgKiAgIGNvbnNvbGUubG9nKGxlbmd0aCk7XG4gICAqIH0pO1xuICAgKi9cbiAgZ2V0IGxlbmd0aCgpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZU1hcC5zaXplO1xuXG4gIH1cblxuICAvKiBVc2UgdGhlIGBTdG9yYWdlTWFwYCBzZXJ2aWNlIHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24gKi9cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHN0b3JhZ2VNYXA6IFN0b3JhZ2VNYXApIHt9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBpdGVtIHZhbHVlIGluIHN0b3JhZ2UuXG4gICAqIFRoZSBzaWduYXR1cmUgaGFzIG1hbnkgb3ZlcmxvYWRzIGR1ZSB0byB2YWxpZGF0aW9uLCAqKnBsZWFzZSByZWZlciB0byB0aGUgZG9jdW1lbnRhdGlvbi4qKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFpbi9kb2NzL1ZBTElEQVRJT04ubWR9XG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHBhcmFtIHNjaGVtYSBPcHRpb25hbCBKU09OIHNjaGVtYSB0byB2YWxpZGF0ZSB0aGUgZGF0YS5cbiAgICogKipOb3RlIHlvdSBtdXN0IHBhc3MgdGhlIHNjaGVtYSBkaXJlY3RseSBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LioqXG4gICAqICoqUGFzc2luZyB0aGUgc2NoZW1hIGluIGFuIG9iamVjdCBgeyBzY2hlbWEgfWAgaXMgZGVwcmVjYXRlZCBhbmQgb25seSBoZXJlKipcbiAgICogKipmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eTogaXQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uKipcbiAgICogQHJldHVybnMgVGhlIGl0ZW0ncyB2YWx1ZSBpZiB0aGUga2V5IGV4aXN0cywgYG51bGxgIG90aGVyd2lzZSwgd3JhcHBlZCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLmdldCgna2V5JywgeyB0eXBlOiAnc3RyaW5nJyB9KS5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgKiAgIHJlc3VsdDsgLy8gc3RyaW5nIG9yIG51bGxcbiAgICogfSk7XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGludGVyZmFjZSBVc2VyIHtcbiAgICogICBmaXJzdE5hbWU6IHN0cmluZztcbiAgICogICBsYXN0TmFtZT86IHN0cmluZztcbiAgICogfVxuICAgKlxuICAgKiBjb25zdCBzY2hlbWEgPSB7XG4gICAqICAgdHlwZTogJ29iamVjdCcsXG4gICAqICAgcHJvcGVydGllczoge1xuICAgKiAgICAgZmlyc3ROYW1lOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAqICAgICBsYXN0TmFtZTogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgKiAgIH0sXG4gICAqICAgcmVxdWlyZWQ6IFsnZmlyc3ROYW1lJ11cbiAgICogfTtcbiAgICpcbiAgICogdGhpcy5sb2NhbFN0b3JhZ2UuZ2V0PFVzZXI+KCd1c2VyJywgc2NoZW1hKS5zdWJzY3JpYmUoKHVzZXIpID0+IHtcbiAgICogICBpZiAodXNlcikge1xuICAgKiAgICAgdXNlci5maXJzdE5hbWU7XG4gICAqICAgfVxuICAgKiB9KTtcbiAgICovXG4gIGdldEl0ZW08VCA9IHN0cmluZz4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYVN0cmluZyk6IE9ic2VydmFibGU8c3RyaW5nIHwgbnVsbD47IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGdldEl0ZW08VCA9IG51bWJlcj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUludGVnZXIgfCBKU09OU2NoZW1hTnVtYmVyKTogT2JzZXJ2YWJsZTxudW1iZXIgfCBudWxsPjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZ2V0SXRlbTxUID0gYm9vbGVhbj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUJvb2xlYW4pOiBPYnNlcnZhYmxlPGJvb2xlYW4gfCBudWxsPjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZ2V0SXRlbTxUID0gc3RyaW5nW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFTdHJpbmc+KTogT2JzZXJ2YWJsZTxzdHJpbmdbXSB8IG51bGw+OyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBnZXRJdGVtPFQgPSBudW1iZXJbXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYUludGVnZXIgfCBKU09OU2NoZW1hTnVtYmVyPik6IE9ic2VydmFibGU8bnVtYmVyW10gfCBudWxsPjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZ2V0SXRlbTxUID0gYm9vbGVhbltdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hQm9vbGVhbj4pOiBPYnNlcnZhYmxlPGJvb2xlYW5bXSB8IG51bGw+OyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBnZXRJdGVtPFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hIHwgeyBzY2hlbWE6IEpTT05TY2hlbWEgfSk6IE9ic2VydmFibGU8VCB8IG51bGw+OyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBnZXRJdGVtPFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8dW5rbm93bj47IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGdldEl0ZW08VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBzY2hlbWE/OiBKU09OU2NoZW1hIHwgeyBzY2hlbWE6IEpTT05TY2hlbWEgfSB8IHVuZGVmaW5lZCk6IE9ic2VydmFibGU8dW5rbm93bj4ge1xuXG4gICAgaWYgKHNjaGVtYSkge1xuXG4gICAgICAvKiBCYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggdmVyc2lvbiA8PSA3ICovXG4gICAgICBzY2hlbWEgPSAoJ3NjaGVtYScgaW4gc2NoZW1hKSA/IHNjaGVtYS5zY2hlbWEgOiBzY2hlbWE7XG5cbiAgICB9XG5cbiAgICByZXR1cm4gKHNjaGVtYSA/IHRoaXMuc3RvcmFnZU1hcC5nZXQ8VD4oa2V5LCBzY2hlbWEpIDogdGhpcy5zdG9yYWdlTWFwLmdldChrZXkpKS5waXBlKFxuICAgICAgLyogVHJhbnNmb3JtIGB1bmRlZmluZWRgIGludG8gYG51bGxgIHRvIGFsaWduIHdpdGggYGxvY2FsU3RvcmFnZWAgQVBJICovXG4gICAgICBtYXAoKHZhbHVlKSA9PiAodmFsdWUgIT09IHVuZGVmaW5lZCkgPyB2YWx1ZSA6IG51bGwpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYW4gaXRlbSBpbiBzdG9yYWdlLlxuICAgKiBOb3RlIHRoYXQgc2V0dGluZyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgd2lsbCByZW1vdmUgdGhlIGl0ZW0gdG8gYXZvaWQgc29tZSBicm93c2VycyBpc3N1ZXMuXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHBhcmFtIGRhdGEgVGhlIGl0ZW0ncyB2YWx1ZVxuICAgKiBAcGFyYW0gc2NoZW1hIE9wdGlvbmFsIEpTT04gc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBkYXRhXG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5sb2NhbFN0b3JhZ2Uuc2V0KCdrZXknLCAndmFsdWUnKS5zdWJzY3JpYmUoKCkgPT4ge30pO1xuICAgKi9cbiAgc2V0SXRlbShrZXk6IHN0cmluZywgZGF0YTogdW5rbm93biwgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZU1hcC5zZXQoa2V5LCBkYXRhLCBzY2hlbWEpLnBpcGUoXG4gICAgICAvKiBUcmFuc2Zvcm0gYHVuZGVmaW5lZGAgaW50byBgdHJ1ZWAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCB2NyAqL1xuICAgICAgbWFwVG8odHJ1ZSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhbiBpdGVtIGluIHN0b3JhZ2VcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLmRlbGV0ZSgna2V5Jykuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIHJlbW92ZUl0ZW0oa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VNYXAuZGVsZXRlKGtleSkucGlwZShcbiAgICAgIC8qIFRyYW5zZm9ybSBgdW5kZWZpbmVkYCBpbnRvIGB0cnVlYCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHY3ICovXG4gICAgICBtYXBUbyh0cnVlKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGFsbCBpdGVtcyBpbiBzdG9yYWdlXG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5sb2NhbFN0b3JhZ2UuY2xlYXIoKS5zdWJzY3JpYmUoKCkgPT4ge30pO1xuICAgKi9cbiAgY2xlYXIoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlTWFwLmNsZWFyKCkucGlwZShcbiAgICAgIC8qIFRyYW5zZm9ybSBgdW5kZWZpbmVkYCBpbnRvIGB0cnVlYCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHY3ICovXG4gICAgICBtYXBUbyh0cnVlKSxcbiAgICApO1xuXG4gIH1cblxufVxuIl19