Socket
Socket
Sign inDemoInstall

@ngx-pwa/local-storage

Package Overview
Dependencies
5
Maintainers
1
Versions
125
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 10.0.0-1 to 10.0.0-2

2

bundles/ngx-pwa-local-storage.umd.min.js

@@ -15,3 +15,3 @@ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("@angular/common"),require("rxjs"),require("rxjs/operators")):"function"==typeof define&&define.amd?define("@ngx-pwa/local-storage",["exports","@angular/core","@angular/common","rxjs","rxjs/operators"],t):t(((e=e||self)["ngx-pwa"]=e["ngx-pwa"]||{},e["ngx-pwa"]["local-storage"]={}),e.ng.core,e.ng.common,e.rxjs,e.rxjs.operators)}(this,(function(e,t,r,n,o){"use strict";

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */var a=function(e,t){return(a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};function i(e,t){function r(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}function u(e,t,r,n){var o,a=arguments.length,i=a<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,r,n);else for(var u=e.length-1;u>=0;u--)(o=e[u])&&(i=(a<3?o(i):a>3?o(t,r,i):o(t,r))||i);return a>3&&i&&Object.defineProperty(t,r,i),i}function c(e,t){return function(r,n){t(r,n,e)}}function s(e){var t="function"==typeof Symbol&&Symbol.iterator,r=t&&e[t],n=0;if(r)return r.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&n>=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function p(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,o,a=r.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(n=a.next()).done;)i.push(n.value)}catch(e){o={error:e}}finally{try{n&&!n.done&&(r=a.return)&&r.call(a)}finally{if(o)throw o.error}}return i}function f(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(p(arguments[t]));return e}e.JSONValidator=function(){function e(){}return e.prototype.validate=function(e,t){switch(t.type){case"string":return this.validateString(e,t);case"number":case"integer":return this.validateNumber(e,t);case"boolean":return this.validateBoolean(e,t);case"array":return this.validateArray(e,t);case"object":return this.validateObject(e,t)}},e.prototype.validateString=function(e,t){if("string"!=typeof e)return!1;if(!this.validateConst(e,t))return!1;if(!this.validateEnum(e,t))return!1;if(void 0!==t.maxLength&&e.length>t.maxLength)return!1;if(void 0!==t.minLength&&e.length<t.minLength)return!1;if(t.pattern){var r=null;try{r=new RegExp(t.pattern)}catch(e){}if(r&&!r.test(e))return!1}return!0},e.prototype.validateNumber=function(e,t){return"number"==typeof e&&(!("integer"===t.type&&!Number.isInteger(e))&&(!!this.validateConst(e,t)&&(!!this.validateEnum(e,t)&&(!(t.multipleOf&&!Number.isInteger(e/t.multipleOf))&&(!(void 0!==t.maximum&&e>t.maximum)&&(!(void 0!==t.exclusiveMaximum&&e>=t.exclusiveMaximum)&&(!(void 0!==t.minimum&&e<t.minimum)&&!(void 0!==t.exclusiveMinimum&&e<=t.exclusiveMinimum))))))))},e.prototype.validateBoolean=function(e,t){return"boolean"==typeof e&&!!this.validateConst(e,t)},e.prototype.validateArray=function(e,t){var r,n;if(!Array.isArray(e))return!1;if(void 0!==t.maxItems&&e.length>t.maxItems)return!1;if(void 0!==t.minItems&&e.length<t.minItems)return!1;if(t.uniqueItems){var o=new Set(e);if(e.length!==o.size)return!1}if(Array.isArray(t.items))return this.validateTuple(e,t.items);try{for(var a=s(e),i=a.next();!i.done;i=a.next()){var u=i.value;if(!this.validate(u,t.items))return!1}}catch(e){r={error:e}}finally{try{i&&!i.done&&(n=a.return)&&n.call(a)}finally{if(r)throw r.error}}return!0},e.prototype.validateTuple=function(e,t){if(e.length!==t.length)return!1;for(var r=0;r<t.length;r+=1)if(!this.validate(e[r],t[r]))return!1;return!0},e.prototype.validateObject=function(e,t){var r,n;if("object"!=typeof e||null===e)return!1;if(Object.keys(t.properties).length<Object.keys(e).length)return!1;if(t.required)try{for(var o=s(t.required),a=o.next();!a.done;a=o.next()){var i=a.value;if(!e.hasOwnProperty(i))return!1}}catch(e){r={error:e}}finally{try{a&&!a.done&&(n=o.return)&&n.call(o)}finally{if(r)throw r.error}}for(var u in t.properties)if(t.properties.hasOwnProperty(u)&&e.hasOwnProperty(u)&&!this.validate(e[u],t.properties[u]))return!1;return!0},e.prototype.validateConst=function(e,t){return!t.const||e===t.const},e.prototype.validateEnum=function(e,t){return!t.enum||t.enum.includes(e)},e}(),e.JSONValidator.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e.JSONValidator},token:e.JSONValidator,providedIn:"root"}),e.JSONValidator=u([t.Injectable({providedIn:"root"})],e.JSONValidator);var l=new t.InjectionToken("localStoragePrefix",{providedIn:"root",factory:function(){return""}}),d=new t.InjectionToken("localStorageIDBDBName",{providedIn:"root",factory:function(){return"ngStorage"}}),y=new t.InjectionToken("localStorageIDBDBVersion",{providedIn:"root",factory:function(){return 1}}),h=new t.InjectionToken("localStorageIDBStoreName",{providedIn:"root",factory:function(){return"localStorage"}}),v=new t.InjectionToken("localStorageIDBWrap",{providedIn:"root",factory:function(){return!0}}),g=function(e){function t(){var t=e.apply(this,f(arguments))||this;return t.message="indexedDB is not working",t}return i(t,e),t}(Error),m="The storage is currently localStorage,\nwhere data must be serialized, and the provided data can't be serialized.",b=function(e){function t(){var t=e.apply(this,f(arguments))||this;return t.message=m,t}return i(t,e),t}(Error),I=function(){function e(e,t,r,o){void 0===e&&(e="ngStorage"),void 0===t&&(t="localStorage"),void 0===r&&(r=1),void 0===o&&(o=!0),this.database=new n.ReplaySubject(1),this.wrapIndex="value",this.dbName=e,this.storeName=t,this.dbVersion=r,this.noWrap=o,this.connect()}return Object.defineProperty(e.prototype,"backingStore",{get:function(){return{database:this.dbName,store:this.storeName,version:this.dbVersion}},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"size",{get:function(){return this.transaction("readonly").pipe(o.mergeMap((function(e){var t=e.store,r=e.events,n=t.count();return r.pipe(o.map((function(){return n.result})))})),o.first())},enumerable:!0,configurable:!0}),e.prototype.get=function(e){var t=this;return this.transaction("readonly").pipe(o.mergeMap((function(r){var n=r.store,a=r.events,i=n.get(e);return a.pipe(o.map((function(){if(void 0!==i.result&&null!==i.result)return!t.noWrap&&"object"==typeof i.result&&t.wrapIndex in i.result&&void 0!==i.result[t.wrapIndex]&&null!==i.result[t.wrapIndex]?i.result[t.wrapIndex]:i.result})))})),o.first())},e.prototype.set=function(e,t){var r=this;return void 0===t?this.delete(e):this.transaction("readwrite").pipe(o.mergeMap((function(n){var a,i=n.store,u=n.events,c=r.noWrap?t:((a={})[r.wrapIndex]=t,a);return i.put(c,e),u.pipe(o.mapTo(void 0))})),o.first())},e.prototype.delete=function(e){return this.transaction("readwrite").pipe(o.mergeMap((function(t){var r=t.store,n=t.events;return r.delete(e),n.pipe(o.mapTo(void 0))})),o.first())},e.prototype.clear=function(){return this.transaction("readwrite").pipe(o.mergeMap((function(e){var t=e.store,r=e.events;return t.clear(),r.pipe(o.mapTo(void 0))})),o.first())},e.prototype.keys=function(){var e=this;return this.transaction("readonly").pipe(o.first(),o.mergeMap((function(t){var r=t.store,a="openKeyCursor"in r?r.openKeyCursor():r.openCursor(),i=n.fromEvent(a,"success").pipe(o.takeWhile((function(){return null!==a.result})),o.map((function(){return a.result.key.toString()})),o.tap((function(){a.result.continue()}))),u=e.listenError(a);return n.race([i,u])})))},e.prototype.has=function(e){return this.transaction("readonly").pipe(o.mergeMap((function(t){var r=t.store,n=t.events,a="getKey"in r?r.getKey(e):r.get(e);return n.pipe(o.map((function(){return void 0!==a.result})))})),o.first())},e.prototype.connect=function(){var e,t=this;try{e=indexedDB.open(this.dbName,this.dbVersion)}catch(e){return void this.database.error(new g)}this.createStore(e);var r=n.fromEvent(e,"success"),a=this.listenError(e);n.race([r,a]).pipe(o.first()).subscribe({next:function(){t.database.next(e.result)},error:function(){t.database.error(new g)}})},e.prototype.createStore=function(e){var t=this;n.fromEvent(e,"upgradeneeded").pipe(o.first()).subscribe({next:function(){e.result.objectStoreNames.contains(t.storeName)||e.result.createObjectStore(t.storeName)}})},e.prototype.transaction=function(e){var t=this;return this.database.pipe(o.mergeMap((function(r){var o;try{o=r.transaction([t.storeName],e)}catch(e){return n.throwError(e)}var a=o.objectStore(t.storeName),i=t.listenTransactionEvents(o);return n.of({store:a,events:i})})))},e.prototype.listenError=function(e){return n.fromEvent(e,"error").pipe(o.mergeMap((function(){return n.throwError(e.error)})))},e.prototype.listenTransactionEvents=function(e){var t=n.fromEvent(e,"complete"),r=this.listenError(e);return n.race([t,r])},e}();I.ctorParameters=function(){return[{type:void 0,decorators:[{type:t.Inject,args:[d]}]},{type:void 0,decorators:[{type:t.Inject,args:[h]}]},{type:void 0,decorators:[{type:t.Inject,args:[y]}]},{type:void 0,decorators:[{type:t.Inject,args:[v]}]}]},I.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new I(t.ɵɵinject(d),t.ɵɵinject(h),t.ɵɵinject(y),t.ɵɵinject(v))},token:I,providedIn:"root"}),I=u([t.Injectable({providedIn:"root"}),c(0,t.Inject(d)),c(1,t.Inject(h)),c(2,t.Inject(y)),c(3,t.Inject(v))],I);var S=function(){function e(e){void 0===e&&(e=""),this.prefix=e||""}return Object.defineProperty(e.prototype,"size",{get:function(){return n.of(localStorage.length)},enumerable:!0,configurable:!0}),e.prototype.get=function(e){var t,r=localStorage.getItem(this.prefixKey(e));if(null!=r)try{t=JSON.parse(r)}catch(e){return n.throwError(e)}return n.of(t)},e.prototype.set=function(e,t){var r=null,o=Object.getPrototypeOf(t);if("object"==typeof t&&null!==t&&!Array.isArray(t)&&o!==Object.prototype&&null!==o)return n.throwError(new b);try{r=JSON.stringify(t)}catch(e){return n.throwError(e)}try{localStorage.setItem(this.prefixKey(e),r)}catch(e){return n.throwError(e)}return n.of(void 0)},e.prototype.delete=function(e){return localStorage.removeItem(this.prefixKey(e)),n.of(void 0)},e.prototype.clear=function(){return localStorage.clear(),n.of(void 0)},e.prototype.keys=function(){var e=this;return new n.Observable((function(t){for(var r=0;r<localStorage.length;r+=1)t.next(e.getUnprefixedKey(r));t.complete()})).pipe(o.observeOn(n.asyncScheduler))},e.prototype.has=function(e){for(var t=0;t<localStorage.length;t+=1)if(e===this.getUnprefixedKey(t))return n.of(!0);return n.of(!1)},e.prototype.getUnprefixedKey=function(e){var t=localStorage.key(e);return null!==t?this.prefix?t.substr(this.prefix.length):t:null},e.prototype.prefixKey=function(e){return""+this.prefix+e},e}();S.ctorParameters=function(){return[{type:void 0,decorators:[{type:t.Inject,args:[l]}]}]},S.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new S(t.ɵɵinject(l))},token:S,providedIn:"root"}),S=u([t.Injectable({providedIn:"root"}),c(0,t.Inject(l))],S);var j=function(){function e(){this.memoryStorage=new Map}return Object.defineProperty(e.prototype,"size",{get:function(){return n.of(this.memoryStorage.size)},enumerable:!0,configurable:!0}),e.prototype.get=function(e){var t=this.memoryStorage.get(e);return n.of(t)},e.prototype.set=function(e,t){return this.memoryStorage.set(e,t),n.of(void 0)},e.prototype.delete=function(e){return this.memoryStorage.delete(e),n.of(void 0)},e.prototype.clear=function(){return this.memoryStorage.clear(),n.of(void 0)},e.prototype.keys=function(){return n.from(this.memoryStorage.keys())},e.prototype.has=function(e){return n.of(this.memoryStorage.has(e))},e}();function w(e,t,n,o,a,i){try{if(r.isPlatformBrowser(e)&&void 0!==indexedDB&&null!==indexedDB&&"open"in indexedDB)return new I(n,o,a,i);if(r.isPlatformBrowser(e)&&void 0!==localStorage&&null!==localStorage&&"getItem"in localStorage)return new S(t)}catch(e){}return new j}j.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new j},token:j,providedIn:"root"}),j=u([t.Injectable({providedIn:"root"})],j),e.LocalDatabase=function(){},e.LocalDatabase.ɵprov=t.ɵɵdefineInjectable({factory:function(){return w(t.ɵɵinject(t.PLATFORM_ID),t.ɵɵinject(l),t.ɵɵinject(d),t.ɵɵinject(h),t.ɵɵinject(y),t.ɵɵinject(v))},token:e.LocalDatabase,providedIn:"root"}),e.LocalDatabase=u([t.Injectable({providedIn:"root",useFactory:w,deps:[t.PLATFORM_ID,l,d,h,y,v]})],e.LocalDatabase);var x,O="Data stored is not valid against the provided JSON schema.\nCheck your JSON schema, otherwise it means data has been corrupted.",B=function(e){function t(){var t=e.apply(this,f(arguments))||this;return t.message=O,t}return i(t,e),t}(Error);e.StorageMap=function(){function t(t,r,n){void 0===r&&(r=new e.JSONValidator),void 0===n&&(n=""),this.database=t,this.jsonValidator=r,this.LSPrefix=n,this.notifiers=new Map}return Object.defineProperty(t.prototype,"size",{get:function(){var e=this;return this.database.size.pipe(this.catchIDBBroken((function(){return e.database.size})))},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"backingEngine",{get:function(){return this.database instanceof I?"indexedDB":this.database instanceof S?"localStorage":this.database instanceof j?"memory":"unknown"},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"backingStore",{get:function(){return this.database instanceof I?this.database.backingStore:{database:"",store:"",version:0}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"fallbackBackingStore",{get:function(){return this.database instanceof S?{prefix:this.database.prefix}:{prefix:""}},enumerable:!0,configurable:!0}),t.prototype.get=function(e,t){var r=this;return this.database.get(e).pipe(this.catchIDBBroken((function(){return r.database.get(e)})),o.mergeMap((function(e){return null==e?n.of(void 0):t?r.jsonValidator.validate(e,t)?n.of(e):n.throwError(new B):n.of(e)})))},t.prototype.set=function(e,t,r){var a=this;return null==t?this.delete(e):r&&!this.jsonValidator.validate(t,r)?n.throwError(new B):this.database.set(e,t).pipe(this.catchIDBBroken((function(){return a.database.set(e,t)})),o.tap((function(){a.notify(e,t)})))},t.prototype.delete=function(e){var t=this;return this.database.delete(e).pipe(this.catchIDBBroken((function(){return t.database.delete(e)})),o.tap((function(){t.notify(e,void 0)})))},t.prototype.clear=function(){var e=this;return this.database.clear().pipe(this.catchIDBBroken((function(){return e.database.clear()})),o.tap((function(){var t,r;try{for(var n=s(e.notifiers.keys()),o=n.next();!o.done;o=n.next()){var a=o.value;e.notify(a,void 0)}}catch(e){t={error:e}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(t)throw t.error}}})))},t.prototype.keys=function(){var e=this;return this.database.keys().pipe(this.catchIDBBroken((function(){return e.database.keys()})))},t.prototype.has=function(e){var t=this;return this.database.has(e).pipe(this.catchIDBBroken((function(){return t.database.has(e)})))},t.prototype.watch=function(e,t){var r=this.notifiers.get(e);return r||(r=new n.ReplaySubject(1),this.notifiers.set(e,r),this.get(e,t).subscribe({next:function(e){return r.next(e)},error:function(e){return r.error(e)}})),r.asObservable()},t.prototype.notify=function(e,t){var r=this.notifiers.get(e);r&&r.next(t)},t.prototype.catchIDBBroken=function(e){var t=this;return o.catchError((function(r){if(null!=r&&"indexedDB is not working"===r.message){try{"getItem"in localStorage?t.database=new S(t.LSPrefix):t.database=new j}catch(e){t.database=new j}return e()}return n.throwError(r)}))},t}(),e.StorageMap.ctorParameters=function(){return[{type:e.LocalDatabase},{type:e.JSONValidator},{type:void 0,decorators:[{type:t.Inject,args:[l]}]}]},e.StorageMap.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e.StorageMap(t.ɵɵinject(e.LocalDatabase),t.ɵɵinject(e.JSONValidator),t.ɵɵinject(l))},token:e.StorageMap,providedIn:"root"}),e.StorageMap=u([t.Injectable({providedIn:"root"}),c(2,t.Inject(l))],e.StorageMap),e.LocalStorage=function(){function e(e){this.storageMap=e}return Object.defineProperty(e.prototype,"length",{get:function(){return this.storageMap.size},enumerable:!0,configurable:!0}),e.prototype.getItem=function(e,t){if(t){var r="schema"in t?t.schema:t;return this.storageMap.get(e,r).pipe(o.map((function(e){return void 0!==e?e:null})))}return this.storageMap.get(e).pipe(o.map((function(e){return void 0!==e?e:null})))},e.prototype.setItem=function(e,t,r){return this.storageMap.set(e,t,r).pipe(o.mapTo(!0))},e.prototype.removeItem=function(e){return this.storageMap.delete(e).pipe(o.mapTo(!0))},e.prototype.clear=function(){return this.storageMap.clear().pipe(o.mapTo(!0))},e}(),e.LocalStorage.ctorParameters=function(){return[{type:e.StorageMap}]},e.LocalStorage.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e.LocalStorage(t.ɵɵinject(e.StorageMap))},token:e.LocalStorage,providedIn:"root"}),e.LocalStorage=u([t.Injectable({providedIn:"root"})],e.LocalStorage),e.StorageModule=x=function(){function e(){}return e.forRoot=function(e){return{ngModule:x,providers:[e.LSPrefix?{provide:l,useValue:e.LSPrefix}:[],e.IDBDBName?{provide:d,useValue:e.IDBDBName}:[],e.IDBStoreName?{provide:h,useValue:e.IDBStoreName}:[],e.IDBDBVersion?{provide:y,useValue:e.IDBDBVersion}:[],!1===e.IDBNoWrap?{provide:v,useValue:e.IDBNoWrap}:[]]}},e}(),e.StorageModule=x=u([t.NgModule()],e.StorageModule),e.SERIALIZATION_ERROR=m,e.SerializationError=b,e.VALIDATION_ERROR=O,e.ValidationError=B,e.ɵa=w,e.ɵb=l,e.ɵc=d,e.ɵd=y,e.ɵe=h,e.ɵf=v,Object.defineProperty(e,"__esModule",{value:!0})}));
***************************************************************************** */var i=function(e,t){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};function a(e,t){function r(){this.constructor=e}i(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}function u(e,t,r,n){var o,i=arguments.length,a=i<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,n);else for(var u=e.length-1;u>=0;u--)(o=e[u])&&(a=(i<3?o(a):i>3?o(t,r,a):o(t,r))||a);return i>3&&a&&Object.defineProperty(t,r,a),a}function c(e,t){return function(r,n){t(r,n,e)}}Object.create;function s(e){var t="function"==typeof Symbol&&Symbol.iterator,r=t&&e[t],n=0;if(r)return r.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&n>=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function p(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,o,i=r.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(n=i.next()).done;)a.push(n.value)}catch(e){o={error:e}}finally{try{n&&!n.done&&(r=i.return)&&r.call(i)}finally{if(o)throw o.error}}return a}function f(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(p(arguments[t]));return e}Object.create;var l=function(){var e=function(){function e(){}return e.prototype.validate=function(e,t){switch(t.type){case"string":return this.validateString(e,t);case"number":case"integer":return this.validateNumber(e,t);case"boolean":return this.validateBoolean(e,t);case"array":return this.validateArray(e,t);case"object":return this.validateObject(e,t)}},e.prototype.validateString=function(e,t){if("string"!=typeof e)return!1;if(!this.validateConst(e,t))return!1;if(!this.validateEnum(e,t))return!1;if(void 0!==t.maxLength&&e.length>t.maxLength)return!1;if(void 0!==t.minLength&&e.length<t.minLength)return!1;if(t.pattern){var r=null;try{r=new RegExp(t.pattern)}catch(e){}if(r&&!r.test(e))return!1}return!0},e.prototype.validateNumber=function(e,t){return"number"==typeof e&&(!("integer"===t.type&&!Number.isInteger(e))&&(!!this.validateConst(e,t)&&(!!this.validateEnum(e,t)&&(!(t.multipleOf&&!Number.isInteger(e/t.multipleOf))&&(!(void 0!==t.maximum&&e>t.maximum)&&(!(void 0!==t.exclusiveMaximum&&e>=t.exclusiveMaximum)&&(!(void 0!==t.minimum&&e<t.minimum)&&!(void 0!==t.exclusiveMinimum&&e<=t.exclusiveMinimum))))))))},e.prototype.validateBoolean=function(e,t){return"boolean"==typeof e&&!!this.validateConst(e,t)},e.prototype.validateArray=function(e,t){var r,n;if(!Array.isArray(e))return!1;if(void 0!==t.maxItems&&e.length>t.maxItems)return!1;if(void 0!==t.minItems&&e.length<t.minItems)return!1;if(t.uniqueItems){var o=new Set(e);if(e.length!==o.size)return!1}if(Array.isArray(t.items))return this.validateTuple(e,t.items);try{for(var i=s(e),a=i.next();!a.done;a=i.next()){var u=a.value;if(!this.validate(u,t.items))return!1}}catch(e){r={error:e}}finally{try{a&&!a.done&&(n=i.return)&&n.call(i)}finally{if(r)throw r.error}}return!0},e.prototype.validateTuple=function(e,t){if(e.length!==t.length)return!1;for(var r=0;r<t.length;r+=1)if(!this.validate(e[r],t[r]))return!1;return!0},e.prototype.validateObject=function(e,t){var r,n;if("object"!=typeof e||null===e)return!1;if(Object.keys(t.properties).length<Object.keys(e).length)return!1;if(t.required)try{for(var o=s(t.required),i=o.next();!i.done;i=o.next()){var a=i.value;if(!e.hasOwnProperty(a))return!1}}catch(e){r={error:e}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(r)throw r.error}}for(var u in t.properties)if(t.properties.hasOwnProperty(u)&&e.hasOwnProperty(u)&&!this.validate(e[u],t.properties[u]))return!1;return!0},e.prototype.validateConst=function(e,t){return!t.const||e===t.const},e.prototype.validateEnum=function(e,t){return!t.enum||t.enum.includes(e)},e}();return e.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e},token:e,providedIn:"root"}),e=u([t.Injectable({providedIn:"root"})],e)}(),d=new t.InjectionToken("localStoragePrefix",{providedIn:"root",factory:function(){return""}}),y=new t.InjectionToken("localStorageIDBDBName",{providedIn:"root",factory:function(){return"ngStorage"}}),v=new t.InjectionToken("localStorageIDBDBVersion",{providedIn:"root",factory:function(){return 1}}),h=new t.InjectionToken("localStorageIDBStoreName",{providedIn:"root",factory:function(){return"localStorage"}}),g=new t.InjectionToken("localStorageIDBWrap",{providedIn:"root",factory:function(){return!0}}),m=function(e){function t(){var t=e.apply(this,f(arguments))||this;return t.message="indexedDB is not working",t}return a(t,e),t}(Error),b="The storage is currently localStorage,\nwhere data must be serialized, and the provided data can't be serialized.",I=function(e){function t(){var t=e.apply(this,f(arguments))||this;return t.message=b,t}return a(t,e),t}(Error),j=function(){var e=function(){function e(e,t,r,o){void 0===e&&(e="ngStorage"),void 0===t&&(t="localStorage"),void 0===r&&(r=1),void 0===o&&(o=!0),this.database=new n.ReplaySubject(1),this.wrapIndex="value",this.dbName=e,this.storeName=t,this.dbVersion=r,this.noWrap=o,this.connect()}return Object.defineProperty(e.prototype,"backingStore",{get:function(){return{database:this.dbName,store:this.storeName,version:this.dbVersion}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"size",{get:function(){return this.transaction("readonly").pipe(o.mergeMap((function(e){var t=e.store,r=e.events,n=t.count();return r.pipe(o.map((function(){return n.result})))})),o.first())},enumerable:!1,configurable:!0}),e.prototype.get=function(e){var t=this;return this.transaction("readonly").pipe(o.mergeMap((function(r){var n=r.store,i=r.events,a=n.get(e);return i.pipe(o.map((function(){if(void 0!==a.result&&null!==a.result)return!t.noWrap&&"object"==typeof a.result&&t.wrapIndex in a.result&&void 0!==a.result[t.wrapIndex]&&null!==a.result[t.wrapIndex]?a.result[t.wrapIndex]:a.result})))})),o.first())},e.prototype.set=function(e,t){var r=this;return void 0===t?this.delete(e):this.transaction("readwrite").pipe(o.mergeMap((function(n){var i,a=n.store,u=n.events,c=r.noWrap?t:((i={})[r.wrapIndex]=t,i);return a.put(c,e),u.pipe(o.mapTo(void 0))})),o.first())},e.prototype.delete=function(e){return this.transaction("readwrite").pipe(o.mergeMap((function(t){var r=t.store,n=t.events;return r.delete(e),n.pipe(o.mapTo(void 0))})),o.first())},e.prototype.clear=function(){return this.transaction("readwrite").pipe(o.mergeMap((function(e){var t=e.store,r=e.events;return t.clear(),r.pipe(o.mapTo(void 0))})),o.first())},e.prototype.keys=function(){var e=this;return this.transaction("readonly").pipe(o.first(),o.mergeMap((function(t){var r=t.store,i="openKeyCursor"in r?r.openKeyCursor():r.openCursor(),a=n.fromEvent(i,"success").pipe(o.takeWhile((function(){return null!==i.result})),o.map((function(){return i.result.key.toString()})),o.tap((function(){i.result.continue()}))),u=e.listenError(i);return n.race([a,u])})))},e.prototype.has=function(e){return this.transaction("readonly").pipe(o.mergeMap((function(t){var r=t.store,n=t.events,i="getKey"in r?r.getKey(e):r.get(e);return n.pipe(o.map((function(){return void 0!==i.result})))})),o.first())},e.prototype.connect=function(){var e,t=this;try{e=indexedDB.open(this.dbName,this.dbVersion)}catch(e){return void this.database.error(new m)}this.createStore(e);var r=n.fromEvent(e,"success"),i=this.listenError(e);n.race([r,i]).pipe(o.first()).subscribe({next:function(){t.database.next(e.result)},error:function(){t.database.error(new m)}})},e.prototype.createStore=function(e){var t=this;n.fromEvent(e,"upgradeneeded").pipe(o.first()).subscribe({next:function(){e.result.objectStoreNames.contains(t.storeName)||e.result.createObjectStore(t.storeName)}})},e.prototype.transaction=function(e){var t=this;return this.database.pipe(o.mergeMap((function(r){var o;try{o=r.transaction([t.storeName],e)}catch(e){return n.throwError(e)}var i=o.objectStore(t.storeName),a=t.listenTransactionEvents(o);return n.of({store:i,events:a})})))},e.prototype.listenError=function(e){return n.fromEvent(e,"error").pipe(o.mergeMap((function(){return n.throwError(e.error)})))},e.prototype.listenTransactionEvents=function(e){var t=n.fromEvent(e,"complete"),r=this.listenError(e);return n.race([t,r])},e}();return e.ctorParameters=function(){return[{type:void 0,decorators:[{type:t.Inject,args:[y]}]},{type:void 0,decorators:[{type:t.Inject,args:[h]}]},{type:void 0,decorators:[{type:t.Inject,args:[v]}]},{type:void 0,decorators:[{type:t.Inject,args:[g]}]}]},e.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e(t.ɵɵinject(y),t.ɵɵinject(h),t.ɵɵinject(v),t.ɵɵinject(g))},token:e,providedIn:"root"}),e=u([t.Injectable({providedIn:"root"}),c(0,t.Inject(y)),c(1,t.Inject(h)),c(2,t.Inject(v)),c(3,t.Inject(g))],e)}(),w=function(){var e=function(){function e(e){void 0===e&&(e=""),this.prefix=e||""}return Object.defineProperty(e.prototype,"size",{get:function(){return n.of(localStorage.length)},enumerable:!1,configurable:!0}),e.prototype.get=function(e){var t,r=localStorage.getItem(this.prefixKey(e));if(null!=r)try{t=JSON.parse(r)}catch(e){return n.throwError(e)}return n.of(t)},e.prototype.set=function(e,t){var r=null,o=Object.getPrototypeOf(t);if("object"==typeof t&&null!==t&&!Array.isArray(t)&&o!==Object.prototype&&null!==o)return n.throwError(new I);try{r=JSON.stringify(t)}catch(e){return n.throwError(e)}try{localStorage.setItem(this.prefixKey(e),r)}catch(e){return n.throwError(e)}return n.of(void 0)},e.prototype.delete=function(e){return localStorage.removeItem(this.prefixKey(e)),n.of(void 0)},e.prototype.clear=function(){return localStorage.clear(),n.of(void 0)},e.prototype.keys=function(){var e=this;return new n.Observable((function(t){for(var r=0;r<localStorage.length;r+=1)t.next(e.getUnprefixedKey(r));t.complete()})).pipe(o.observeOn(n.asyncScheduler))},e.prototype.has=function(e){for(var t=0;t<localStorage.length;t+=1)if(e===this.getUnprefixedKey(t))return n.of(!0);return n.of(!1)},e.prototype.getUnprefixedKey=function(e){var t=localStorage.key(e);return null!==t?this.prefix?t.substr(this.prefix.length):t:null},e.prototype.prefixKey=function(e){return""+this.prefix+e},e}();return e.ctorParameters=function(){return[{type:void 0,decorators:[{type:t.Inject,args:[d]}]}]},e.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e(t.ɵɵinject(d))},token:e,providedIn:"root"}),e=u([t.Injectable({providedIn:"root"}),c(0,t.Inject(d))],e)}(),x=function(){var e=function(){function e(){this.memoryStorage=new Map}return Object.defineProperty(e.prototype,"size",{get:function(){return n.of(this.memoryStorage.size)},enumerable:!1,configurable:!0}),e.prototype.get=function(e){var t=this.memoryStorage.get(e);return n.of(t)},e.prototype.set=function(e,t){return this.memoryStorage.set(e,t),n.of(void 0)},e.prototype.delete=function(e){return this.memoryStorage.delete(e),n.of(void 0)},e.prototype.clear=function(){return this.memoryStorage.clear(),n.of(void 0)},e.prototype.keys=function(){return n.from(this.memoryStorage.keys())},e.prototype.has=function(e){return n.of(this.memoryStorage.has(e))},e}();return e.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e},token:e,providedIn:"root"}),e=u([t.Injectable({providedIn:"root"})],e)}();function S(e,t,n,o,i,a){try{if(r.isPlatformBrowser(e)&&void 0!==indexedDB&&null!==indexedDB&&"open"in indexedDB)return new j(n,o,i,a);if(r.isPlatformBrowser(e)&&void 0!==localStorage&&null!==localStorage&&"getItem"in localStorage)return new w(t)}catch(e){}return new x}var O=function(){var e=function(){};return e.ɵprov=t.ɵɵdefineInjectable({factory:function(){return S(t.ɵɵinject(t.PLATFORM_ID),t.ɵɵinject(d),t.ɵɵinject(y),t.ɵɵinject(h),t.ɵɵinject(v),t.ɵɵinject(g))},token:e,providedIn:"root"}),e=u([t.Injectable({providedIn:"root",useFactory:S,deps:[t.PLATFORM_ID,d,y,h,v,g]})],e)}(),B="Data stored is not valid against the provided JSON schema.\nCheck your JSON schema, otherwise it means data has been corrupted.",k=function(e){function t(){var t=e.apply(this,f(arguments))||this;return t.message=B,t}return a(t,e),t}(Error),D=function(){var e=function(){function e(e,t,r){void 0===t&&(t=new l),void 0===r&&(r=""),this.database=e,this.jsonValidator=t,this.LSPrefix=r,this.notifiers=new Map}return Object.defineProperty(e.prototype,"size",{get:function(){var e=this;return this.database.size.pipe(this.catchIDBBroken((function(){return e.database.size})))},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"backingEngine",{get:function(){return this.database instanceof j?"indexedDB":this.database instanceof w?"localStorage":this.database instanceof x?"memory":"unknown"},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"backingStore",{get:function(){return this.database instanceof j?this.database.backingStore:{database:"",store:"",version:0}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"fallbackBackingStore",{get:function(){return this.database instanceof w?{prefix:this.database.prefix}:{prefix:""}},enumerable:!1,configurable:!0}),e.prototype.get=function(e,t){var r=this;return this.database.get(e).pipe(this.catchIDBBroken((function(){return r.database.get(e)})),o.mergeMap((function(e){return null==e?n.of(void 0):t?r.jsonValidator.validate(e,t)?n.of(e):n.throwError(new k):n.of(e)})))},e.prototype.set=function(e,t,r){var i=this;return null==t?this.delete(e):r&&!this.jsonValidator.validate(t,r)?n.throwError(new k):this.database.set(e,t).pipe(this.catchIDBBroken((function(){return i.database.set(e,t)})),o.tap((function(){i.notify(e,t)})))},e.prototype.delete=function(e){var t=this;return this.database.delete(e).pipe(this.catchIDBBroken((function(){return t.database.delete(e)})),o.tap((function(){t.notify(e,void 0)})))},e.prototype.clear=function(){var e=this;return this.database.clear().pipe(this.catchIDBBroken((function(){return e.database.clear()})),o.tap((function(){var t,r;try{for(var n=s(e.notifiers.keys()),o=n.next();!o.done;o=n.next()){var i=o.value;e.notify(i,void 0)}}catch(e){t={error:e}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(t)throw t.error}}})))},e.prototype.keys=function(){var e=this;return this.database.keys().pipe(this.catchIDBBroken((function(){return e.database.keys()})))},e.prototype.has=function(e){var t=this;return this.database.has(e).pipe(this.catchIDBBroken((function(){return t.database.has(e)})))},e.prototype.watch=function(e,t){var r=this.notifiers.get(e);return r||(r=new n.ReplaySubject(1),this.notifiers.set(e,r),this.get(e,t).subscribe({next:function(e){return r.next(e)},error:function(e){return r.error(e)}})),r.asObservable()},e.prototype.notify=function(e,t){var r=this.notifiers.get(e);r&&r.next(t)},e.prototype.catchIDBBroken=function(e){var t=this;return o.catchError((function(r){if(null!=r&&"indexedDB is not working"===r.message){try{"getItem"in localStorage?t.database=new w(t.LSPrefix):t.database=new x}catch(e){t.database=new x}return e()}return n.throwError(r)}))},e}();return e.ctorParameters=function(){return[{type:O},{type:l},{type:void 0,decorators:[{type:t.Inject,args:[d]}]}]},e.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e(t.ɵɵinject(O),t.ɵɵinject(l),t.ɵɵinject(d))},token:e,providedIn:"root"}),e=u([t.Injectable({providedIn:"root"}),c(2,t.Inject(d))],e)}(),E=function(){var e=function(){function e(e){this.storageMap=e}return Object.defineProperty(e.prototype,"length",{get:function(){return this.storageMap.size},enumerable:!1,configurable:!0}),e.prototype.getItem=function(e,t){if(t){var r="schema"in t?t.schema:t;return this.storageMap.get(e,r).pipe(o.map((function(e){return void 0!==e?e:null})))}return this.storageMap.get(e).pipe(o.map((function(e){return void 0!==e?e:null})))},e.prototype.setItem=function(e,t,r){return this.storageMap.set(e,t,r).pipe(o.mapTo(!0))},e.prototype.removeItem=function(e){return this.storageMap.delete(e).pipe(o.mapTo(!0))},e.prototype.clear=function(){return this.storageMap.clear().pipe(o.mapTo(!0))},e}();return e.ctorParameters=function(){return[{type:D}]},e.ɵprov=t.ɵɵdefineInjectable({factory:function(){return new e(t.ɵɵinject(D))},token:e,providedIn:"root"}),e=u([t.Injectable({providedIn:"root"})],e)}(),P=function(){var e,r=e=function(){function t(){}return t.forRoot=function(t){return{ngModule:e,providers:[t.LSPrefix?{provide:d,useValue:t.LSPrefix}:[],t.IDBDBName?{provide:y,useValue:t.IDBDBName}:[],t.IDBStoreName?{provide:h,useValue:t.IDBStoreName}:[],t.IDBDBVersion?{provide:v,useValue:t.IDBDBVersion}:[],!1===t.IDBNoWrap?{provide:g,useValue:t.IDBNoWrap}:[]]}},t}();return r=e=u([t.NgModule()],r)}();e.JSONValidator=l,e.LocalDatabase=O,e.LocalStorage=E,e.SERIALIZATION_ERROR=b,e.SerializationError=I,e.StorageMap=D,e.StorageModule=P,e.VALIDATION_ERROR=B,e.ValidationError=k,e.ɵa=S,e.ɵb=d,e.ɵc=y,e.ɵd=v,e.ɵe=h,e.ɵf=g,Object.defineProperty(e,"__esModule",{value:!0})}));
//# sourceMappingURL=ngx-pwa-local-storage.umd.min.js.map

@@ -9,315 +9,318 @@ import { __decorate, __param } from "tslib";

import * as i1 from "../tokens";
let IndexedDBDatabase = class IndexedDBDatabase {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param dbName `indexedDB` database name
* @param storeName `indexedDB` store name
* @param dbVersion `indexedDB` database version
* @param noWrap Flag to not wrap `indexedDB` values for interoperability or to wrap for backward compatibility
*/
constructor(dbName = DEFAULT_IDB_DB_NAME, storeName = DEFAULT_IDB_STORE_NAME, dbVersion = DEFAULT_IDB_DB_VERSION, noWrap = DEFAULT_IDB_NO_WRAP) {
let IndexedDBDatabase = /** @class */ (() => {
let IndexedDBDatabase = class IndexedDBDatabase {
/**
* `indexedDB` database connection, wrapped in a RxJS `ReplaySubject` to be able to access the connection
* even after the connection success event happened
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param dbName `indexedDB` database name
* @param storeName `indexedDB` store name
* @param dbVersion `indexedDB` database version
* @param noWrap Flag to not wrap `indexedDB` values for interoperability or to wrap for backward compatibility
*/
this.database = new ReplaySubject(1);
constructor(dbName = DEFAULT_IDB_DB_NAME, storeName = DEFAULT_IDB_STORE_NAME, dbVersion = DEFAULT_IDB_DB_VERSION, noWrap = DEFAULT_IDB_NO_WRAP) {
/**
* `indexedDB` database connection, wrapped in a RxJS `ReplaySubject` to be able to access the connection
* even after the connection success event happened
*/
this.database = new ReplaySubject(1);
/**
* Index used when wrapping value. *For backward compatibility only.*
*/
this.wrapIndex = 'value';
this.dbName = dbName;
this.storeName = storeName;
this.dbVersion = dbVersion;
this.noWrap = noWrap;
/* Connect to `indexedDB`, with prefix if provided by the user */
this.connect();
}
/**
* Index used when wrapping value. *For backward compatibility only.*
* Information about `indexedDB` connection. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version
*/
this.wrapIndex = 'value';
this.dbName = dbName;
this.storeName = storeName;
this.dbVersion = dbVersion;
this.noWrap = noWrap;
/* Connect to `indexedDB`, with prefix if provided by the user */
this.connect();
}
/**
* Information about `indexedDB` connection. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version
*/
get backingStore() {
return {
database: this.dbName,
store: this.storeName,
version: this.dbVersion,
};
}
/**
* Number of items in our `indexedDB` database and object store
*/
get size() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request to know the number of items */
const request = store.count();
/* Return the result */
return events.pipe(map(() => request.result));
}),
/* The observable will complete after the first value */
first());
}
/**
* Gets an item value in our `indexedDB` store
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in an RxJS `Observable`
*/
get(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request the value with the key provided by the user */
const request = store.get(key);
/* Listen events and return the result */
return events.pipe(map(() => {
if ((request.result !== undefined) && (request.result !== null)) {
/* Prior to v8, the value was wrapped in an `{ value: ...}` object */
if (!this.noWrap && (typeof request.result === 'object') && (this.wrapIndex in request.result) &&
(request.result[this.wrapIndex] !== undefined) && (request.result[this.wrapIndex] !== null)) {
return request.result[this.wrapIndex];
get backingStore() {
return {
database: this.dbName,
store: this.storeName,
version: this.dbVersion,
};
}
/**
* Number of items in our `indexedDB` database and object store
*/
get size() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request to know the number of items */
const request = store.count();
/* Return the result */
return events.pipe(map(() => request.result));
}),
/* The observable will complete after the first value */
first());
}
/**
* Gets an item value in our `indexedDB` store
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in an RxJS `Observable`
*/
get(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request the value with the key provided by the user */
const request = store.get(key);
/* Listen events and return the result */
return events.pipe(map(() => {
if ((request.result !== undefined) && (request.result !== null)) {
/* Prior to v8, the value was wrapped in an `{ value: ...}` object */
if (!this.noWrap && (typeof request.result === 'object') && (this.wrapIndex in request.result) &&
(request.result[this.wrapIndex] !== undefined) && (request.result[this.wrapIndex] !== null)) {
return request.result[this.wrapIndex];
}
else {
/* Cast to the wanted type */
return request.result;
}
}
else {
/* Cast to the wanted type */
return request.result;
}
}
/* Return `undefined` if the value is empty */
return undefined;
}));
}),
/* The observable will complete after the first value */
first());
}
/**
* Sets an item in our `indexedDB` store
* @param key The item's key
* @param data The item's value
* @returns An RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
/* Storing `undefined` in `indexedDb` can cause issues in some browsers so removing item instead */
if (data === undefined) {
return this.delete(key);
/* Return `undefined` if the value is empty */
return undefined;
}));
}),
/* The observable will complete after the first value */
first());
}
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Prior to v8, data was wrapped in a `{ value: ... }` object */
const dataToStore = this.noWrap ? data : { [this.wrapIndex]: data };
/* Add if the item is not existing yet, or update otherwise */
store.put(dataToStore, key);
/* Listen to events and return `undefined` as no value is expected */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
/**
* Deletes an item in our `indexedDB` store
* @param key The item's key
* @returns An RxJS `Observable` to wait the end of the operation
*/
delete(key) {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete the item in store */
store.delete(key);
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
/**
* Deletes all items from our `indexedDB` objet store
* @returns An RxJS `Observable` to wait the end of the operation
*/
clear() {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete all items in object store */
store.clear();
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete */
first());
}
/**
* Get all the keys in our `indexedDB` store
* @returns An RxJS `Observable` iterating on each key
*/
keys() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(
/* `first()` is used as the final operator in other methods to complete the `Observable`
* (as it all starts from a `ReplaySubject` which never ends),
* but as this method is iterating over multiple values, `first()` **must** be used here */
first(), mergeMap((transactionData) => {
const { store } = transactionData;
/* Open a cursor on the store
* `.openKeyCursor()` is better for performance, but only available in indexedDB v2 (missing in IE/Edge)
* Avoid issues like https://github.com/cyrilletuzi/angular-async-local-storage/issues/69 */
const request = ('openKeyCursor' in store) ? store.openKeyCursor() : store.openCursor();
/* Listen to success event */
const success$ = fromEvent(request, 'success').pipe(
/* Stop the `Observable` when the cursor is `null` */
takeWhile(() => (request.result !== null)),
/* This lib only allows string keys, but user could have added other types of keys from outside
* It's OK to cast as the cursor as been tested in the previous operator */
map(() => request.result.key.toString()),
/* Iterate on the cursor */
tap(() => { request.result.continue(); }));
/* Listen to error event and if so, throw an error */
const error$ = this.listenError(request);
/* Choose the first event to occur */
return race([success$, error$]);
}));
}
/**
* Check if a key exists in our `indexedDB` store
* @returns An RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Check if the key exists in the store
* `getKey()` is better but only available in `indexedDB` v2 (Chrome >= 58, missing in IE/Edge).
* In older browsers, the value is checked instead, but it could lead to an exception
* if `undefined` was stored outside of this lib (e.g. directly with the native `indexedDB` API).
* Fixes https://github.com/cyrilletuzi/angular-async-local-storage/issues/69
*/
const request = ('getKey' in store) ? store.getKey(key) : store.get(key);
/* Listen to events and return `true` or `false` */
return events.pipe(map(() => (request.result !== undefined) ? true : false));
}),
/* The observable will complete */
first());
}
/**
* Connects to `indexedDB` and creates the object store on first time
*/
connect() {
let request;
/* Connect to `indexedDB`
* Will fail in Safari cross-origin iframes
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/42} */
try {
/* Do NOT explicit `window` here, as `indexedDB` could be used from a web worker too */
request = indexedDB.open(this.dbName, this.dbVersion);
/**
* Sets an item in our `indexedDB` store
* @param key The item's key
* @param data The item's value
* @returns An RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
/* Storing `undefined` in `indexedDb` can cause issues in some browsers so removing item instead */
if (data === undefined) {
return this.delete(key);
}
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Prior to v8, data was wrapped in a `{ value: ... }` object */
const dataToStore = this.noWrap ? data : { [this.wrapIndex]: data };
/* Add if the item is not existing yet, or update otherwise */
store.put(dataToStore, key);
/* Listen to events and return `undefined` as no value is expected */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
catch (_a) {
this.database.error(new IDBBrokenError());
return;
/**
* Deletes an item in our `indexedDB` store
* @param key The item's key
* @returns An RxJS `Observable` to wait the end of the operation
*/
delete(key) {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete the item in store */
store.delete(key);
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
/* Create store on first connection */
this.createStore(request);
/* Listen to success and error events */
const success$ = fromEvent(request, 'success');
const error$ = this.listenError(request);
/* Choose the first to occur */
race([success$, error$])
/**
* Deletes all items from our `indexedDB` objet store
* @returns An RxJS `Observable` to wait the end of the operation
*/
clear() {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete all items in object store */
store.clear();
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Register the database connection in the `ReplaySubject` for further access */
this.database.next(request.result);
},
error: () => {
/* Firefox private mode issue: fallback storage if IndexedDb connection is failing
* @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=781982}
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/26} */
this.database.error(new IDBBrokenError());
},
});
}
/**
* Create store on first use of `indexedDB`
* @param request `indexedDB` database opening request
*/
createStore(request) {
/* Listen to the event fired on first connection */
fromEvent(request, 'upgradeneeded')
first());
}
/**
* Get all the keys in our `indexedDB` store
* @returns An RxJS `Observable` iterating on each key
*/
keys() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(
/* `first()` is used as the final operator in other methods to complete the `Observable`
* (as it all starts from a `ReplaySubject` which never ends),
* but as this method is iterating over multiple values, `first()` **must** be used here */
first(), mergeMap((transactionData) => {
const { store } = transactionData;
/* Open a cursor on the store
* `.openKeyCursor()` is better for performance, but only available in indexedDB v2 (missing in IE/Edge)
* Avoid issues like https://github.com/cyrilletuzi/angular-async-local-storage/issues/69 */
const request = ('openKeyCursor' in store) ? store.openKeyCursor() : store.openCursor();
/* Listen to success event */
const success$ = fromEvent(request, 'success').pipe(
/* Stop the `Observable` when the cursor is `null` */
takeWhile(() => (request.result !== null)),
/* This lib only allows string keys, but user could have added other types of keys from outside
* It's OK to cast as the cursor as been tested in the previous operator */
map(() => request.result.key.toString()),
/* Iterate on the cursor */
tap(() => { request.result.continue(); }));
/* Listen to error event and if so, throw an error */
const error$ = this.listenError(request);
/* Choose the first event to occur */
return race([success$, error$]);
}));
}
/**
* Check if a key exists in our `indexedDB` store
* @returns An RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Check if the key exists in the store
* `getKey()` is better but only available in `indexedDB` v2 (Chrome >= 58, missing in IE/Edge).
* In older browsers, the value is checked instead, but it could lead to an exception
* if `undefined` was stored outside of this lib (e.g. directly with the native `indexedDB` API).
* Fixes https://github.com/cyrilletuzi/angular-async-local-storage/issues/69
*/
const request = ('getKey' in store) ? store.getKey(key) : store.get(key);
/* Listen to events and return `true` or `false` */
return events.pipe(map(() => (request.result !== undefined) ? true : false));
}),
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Check if the store already exists, to avoid error */
if (!request.result.objectStoreNames.contains(this.storeName)) {
/* Create the object store */
request.result.createObjectStore(this.storeName);
}
}
});
}
/**
* Open an `indexedDB` transaction and get our store
* @param mode `readonly` or `readwrite`
* @returns An `indexedDB` transaction store and events, wrapped in an RxJS `Observable`
*/
transaction(mode) {
/* From the `indexedDB` connection, open a transaction and get the store */
return this.database
.pipe(mergeMap((database) => {
let transaction;
first());
}
/**
* Connects to `indexedDB` and creates the object store on first time
*/
connect() {
let request;
/* Connect to `indexedDB`
* Will fail in Safari cross-origin iframes
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/42} */
try {
transaction = database.transaction([this.storeName], mode);
/* Do NOT explicit `window` here, as `indexedDB` could be used from a web worker too */
request = indexedDB.open(this.dbName, this.dbVersion);
}
catch (error) {
/* The store could have been deleted from outside */
return throwError(error);
catch (_a) {
this.database.error(new IDBBrokenError());
return;
}
/* Get the store from the transaction */
const store = transaction.objectStore(this.storeName);
/* Listen transaction `complete` and `error` events */
const events = this.listenTransactionEvents(transaction);
return of({ store, events });
}));
}
/**
* Listen errors on a transaction or request, and throw if trigerred
* @param transactionOrRequest `indexedDb` transaction or request to listen
* @returns An `Observable` listening to errors
*/
listenError(transactionOrRequest) {
return fromEvent(transactionOrRequest, 'error').pipe(
/* Throw on error to be able to catch errors in RxJS way */
mergeMap(() => throwError(transactionOrRequest.error)));
}
/**
* Listen transaction `complete` and `error` events
* @param transaction Transaction to listen
* @returns An `Observable` listening to transaction `complete` and `error` events
*/
listenTransactionEvents(transaction) {
/* Listen to the `complete` event */
const complete$ = fromEvent(transaction, 'complete');
/* Listen to the `error` event */
const error$ = this.listenError(transaction);
/* Choose the first event to occur */
return race([complete$, error$]);
}
};
IndexedDBDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_STORE_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_VERSION,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_NO_WRAP,] }] }
];
IndexedDBDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function IndexedDBDatabase_Factory() { return new IndexedDBDatabase(i0.ɵɵinject(i1.IDB_DB_NAME), i0.ɵɵinject(i1.IDB_STORE_NAME), i0.ɵɵinject(i1.IDB_DB_VERSION), i0.ɵɵinject(i1.IDB_NO_WRAP)); }, token: IndexedDBDatabase, providedIn: "root" });
IndexedDBDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(IDB_DB_NAME)),
__param(1, Inject(IDB_STORE_NAME)),
__param(2, Inject(IDB_DB_VERSION)),
__param(3, Inject(IDB_NO_WRAP))
], IndexedDBDatabase);
/* Create store on first connection */
this.createStore(request);
/* Listen to success and error events */
const success$ = fromEvent(request, 'success');
const error$ = this.listenError(request);
/* Choose the first to occur */
race([success$, error$])
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Register the database connection in the `ReplaySubject` for further access */
this.database.next(request.result);
},
error: () => {
/* Firefox private mode issue: fallback storage if IndexedDb connection is failing
* @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=781982}
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/26} */
this.database.error(new IDBBrokenError());
},
});
}
/**
* Create store on first use of `indexedDB`
* @param request `indexedDB` database opening request
*/
createStore(request) {
/* Listen to the event fired on first connection */
fromEvent(request, 'upgradeneeded')
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Check if the store already exists, to avoid error */
if (!request.result.objectStoreNames.contains(this.storeName)) {
/* Create the object store */
request.result.createObjectStore(this.storeName);
}
}
});
}
/**
* Open an `indexedDB` transaction and get our store
* @param mode `readonly` or `readwrite`
* @returns An `indexedDB` transaction store and events, wrapped in an RxJS `Observable`
*/
transaction(mode) {
/* From the `indexedDB` connection, open a transaction and get the store */
return this.database
.pipe(mergeMap((database) => {
let transaction;
try {
transaction = database.transaction([this.storeName], mode);
}
catch (error) {
/* The store could have been deleted from outside */
return throwError(error);
}
/* Get the store from the transaction */
const store = transaction.objectStore(this.storeName);
/* Listen transaction `complete` and `error` events */
const events = this.listenTransactionEvents(transaction);
return of({ store, events });
}));
}
/**
* Listen errors on a transaction or request, and throw if trigerred
* @param transactionOrRequest `indexedDb` transaction or request to listen
* @returns An `Observable` listening to errors
*/
listenError(transactionOrRequest) {
return fromEvent(transactionOrRequest, 'error').pipe(
/* Throw on error to be able to catch errors in RxJS way */
mergeMap(() => throwError(transactionOrRequest.error)));
}
/**
* Listen transaction `complete` and `error` events
* @param transaction Transaction to listen
* @returns An `Observable` listening to transaction `complete` and `error` events
*/
listenTransactionEvents(transaction) {
/* Listen to the `complete` event */
const complete$ = fromEvent(transaction, 'complete');
/* Listen to the `error` event */
const error$ = this.listenError(transaction);
/* Choose the first event to occur */
return race([complete$, error$]);
}
};
IndexedDBDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_STORE_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_VERSION,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_NO_WRAP,] }] }
];
IndexedDBDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function IndexedDBDatabase_Factory() { return new IndexedDBDatabase(i0.ɵɵinject(i1.IDB_DB_NAME), i0.ɵɵinject(i1.IDB_STORE_NAME), i0.ɵɵinject(i1.IDB_DB_VERSION), i0.ɵɵinject(i1.IDB_NO_WRAP)); }, token: IndexedDBDatabase, providedIn: "root" });
IndexedDBDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(IDB_DB_NAME)),
__param(1, Inject(IDB_STORE_NAME)),
__param(2, Inject(IDB_DB_VERSION)),
__param(3, Inject(IDB_NO_WRAP))
], IndexedDBDatabase);
return IndexedDBDatabase;
})();
export { IndexedDBDatabase };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXhlZGRiLWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9kYXRhYmFzZXMvaW5kZXhlZGRiLWRhdGFiYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWMsYUFBYSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsRixPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3RSxPQUFPLEVBQ0wsV0FBVyxFQUFFLGNBQWMsRUFBRSxzQkFBc0IsRUFBRSxjQUFjLEVBQ25FLG1CQUFtQixFQUFFLHNCQUFzQixFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFDOUUsTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7O0FBTTlDLElBQWEsaUJBQWlCLEdBQTlCLE1BQWEsaUJBQWlCO0lBaUM1Qjs7Ozs7O09BTUc7SUFDSCxZQUN1QixTQUFTLG1CQUFtQixFQUN6QixZQUFZLHNCQUFzQixFQUNsQyxZQUFZLHNCQUFzQixFQUNyQyxTQUFTLG1CQUFtQjtRQTNCbkQ7OztXQUdHO1FBQ2dCLGFBQVEsR0FBRyxJQUFJLGFBQWEsQ0FBYyxDQUFDLENBQUMsQ0FBQztRQU9oRTs7V0FFRztRQUNnQixjQUFTLEdBQUcsT0FBTyxDQUFDO1FBZ0JyQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENB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M0Qsb0NBQW9DO1FBQ3BDLE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFckQsaUNBQWlDO1FBQ2pDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFN0MscUNBQXFDO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFFbkMsQ0FBQztDQUVGLENBQUE7OzRDQXZaSSxNQUFNLFNBQUMsV0FBVzs0Q0FDbEIsTUFBTSxTQUFDLGNBQWM7NENBQ3JCLE1BQU0sU0FBQyxjQUFjOzRDQUNyQixNQUFNLFNBQUMsV0FBVzs7O0FBNUNWLGlCQUFpQjtJQUg3QixVQUFVLENBQUM7UUFDVixVQUFVLEVBQUUsTUFBTTtLQUNuQixDQUFDO0lBMENHLFdBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBQ25CLFdBQUEsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFBO0lBQ3RCLFdBQUEsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFBO0lBQ3RCLFdBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFBO0dBNUNYLGlCQUFpQixDQWdjN0I7U0FoY1ksaUJBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBSZXBsYXlTdWJqZWN0LCBmcm9tRXZlbnQsIG9mLCB0aHJvd0Vycm9yLCByYWNlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIG1lcmdlTWFwLCBmaXJzdCwgdGFrZVdoaWxlLCB0YXAsIG1hcFRvIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge1xuICBJREJfREJfTkFNRSwgSURCX1NUT1JFX05BTUUsIERFRkFVTFRfSURCX1NUT1JFX05BTUUsIElEQl9EQl9WRVJTSU9OLFxuICBERUZBVUxUX0lEQl9EQl9OQU1FLCBERUZBVUxUX0lEQl9EQl9WRVJTSU9OLCBJREJfTk9fV1JBUCwgREVGQVVMVF9JREJfTk9fV1JBUFxufSBmcm9tICcuLi90b2tlbnMnO1xuaW1wb3J0IHsgSURCQnJva2VuRXJyb3IgfSBmcm9tICcuL2V4Y2VwdGlvbnMnO1xuaW1wb3J0IHsgTG9jYWxEYXRhYmFzZSB9IGZyb20gJy4vbG9jYWwtZGF0YWJhc2UnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBJbmRleGVkREJEYXRhYmFzZSBpbXBsZW1lbnRzIExvY2FsRGF0YWJhc2Uge1xuXG4gIC8qKlxuICAgKiBgaW5kZXhlZERCYCBkYXRhYmFzZSBuYW1lXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGJOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIGBpbmRleGVkREJgIG9iamVjdCBzdG9yZSBuYW1lXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc3RvcmVOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIGBpbmRleGVkREJgIGRhdGFiYXNlIHZlcnNpb24uIE11c3QgYmUgYW4gdW5zaWduZWQgKippbnRlZ2VyKipcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBkYlZlcnNpb246IG51bWJlcjtcblxuICAvKipcbiAgICogYGluZGV4ZWREQmAgZGF0YWJhc2UgY29ubmVjdGlvbiwgd3JhcHBlZCBpbiBhIFJ4SlMgYFJlcGxheVN1YmplY3RgIHRvIGJlIGFibGUgdG8gYWNjZXNzIHRoZSBjb25uZWN0aW9uXG4gICAqIGV2ZW4gYWZ0ZXIgdGhlIGNvbm5lY3Rpb24gc3VjY2VzcyBldmVudCBoYXBwZW5lZFxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRhdGFiYXNlID0gbmV3IFJlcGxheVN1YmplY3Q8SURCRGF0YWJhc2U+KDEpO1xuXG4gIC8qKlxuICAgKiBGbGFnIHRvIG5vdCB3cmFwIGBpbmRleGVkREJgIHZhbHVlcyBmb3IgaW50ZXJvcGVyYWJpbGl0eSBvciB0byB3cmFwIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG5vV3JhcDogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5kZXggdXNlZCB3aGVuIHdyYXBwaW5nIHZhbHVlLiAqRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgb25seS4qXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgd3JhcEluZGV4ID0gJ3ZhbHVlJztcblxuICAvKipcbiAgICogQ29uc3RydWN0b3IgcGFyYW1zIGFyZSBwcm92aWRlZCBieSBBbmd1bGFyIChidXQgY2FuIGFsc28gYmUgcGFzc2VkIG1hbnVhbGx5IGluIHRlc3RzKVxuICAgKiBAcGFyYW0gZGJOYW1lIGBpbmRleGVkREJgIGRhdGFiYXNlIG5hbWVcbiAgICogQHBhcmFtIHN0b3JlTmFtZSBgaW5kZXhlZERCYCBzdG9yZSBuYW1lXG4gICAqIEBwYXJhbSBkYlZlcnNpb24gYGluZGV4ZWREQmAgZGF0YWJhc2UgdmVyc2lvblxuICAgKiBAcGFyYW0gbm9XcmFwIEZsYWcgdG8gbm90IHdyYXAgYGluZGV4ZWREQmAgdmFsdWVzIGZvciBpbnRlcm9wZXJhYmlsaXR5IG9yIHRvIHdyYXAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoSURCX0RCX05BTUUpIGRiTmFtZSA9IERFRkFVTFRfSURCX0RCX05BTUUsXG4gICAgQEluamVjdChJREJfU1RPUkVfTkFNRSkgc3RvcmVOYW1lID0gREVGQVVMVF9JREJfU1RPUkVfTkFNRSxcbiAgICBASW5qZWN0KElEQl9EQl9WRVJTSU9OKSBkYlZlcnNpb24gPSBERUZBVUxUX0lEQl9EQl9WRVJTSU9OLFxuICAgIEBJbmplY3QoSURCX05PX1dSQVApIG5vV3JhcCA9IERFRkFVTFRfSURCX05PX1dSQVAsXG4gICkge1xuXG4gICAgdGhpcy5kYk5hbWUgPSBkYk5hbWU7XG4gICAgdGhpcy5zdG9yZU5hbWUgPSBzdG9yZU5hbWU7XG4gICAgdGhpcy5kYlZlcnNpb24gPSBkYlZlcnNpb247XG4gICAgdGhpcy5ub1dyYXAgPSBub1dyYXA7XG5cbiAgICAvKiBDb25uZWN0IHRvIGBpbmRleGVkREJgLCB3aXRoIHByZWZpeCBpZiBwcm92aWRlZCBieSB0aGUgdXNlciAqL1xuICAgIHRoaXMuY29ubmVjdCgpO1xuXG4gIH1cblxuICAvKipcbiAgICogSW5mb3JtYXRpb24gYWJvdXQgYGluZGV4ZWREQmAgY29ubmVjdGlvbi4gKk9ubHkgdXNlZnVsIGZvciBpbnRlcm9wZXJhYmlsaXR5LipcbiAgICogQHJldHVybnMgYGluZGV4ZWREQmAgZGF0YWJhc2UgbmFtZSwgc3RvcmUgbmFtZSBhbmQgZGF0YWJhc2UgdmVyc2lvblxuICAgKi9cbiAgZ2V0IGJhY2tpbmdTdG9yZSgpOiB7IGRhdGFiYXNlOiBzdHJpbmcsIHN0b3JlOiBzdHJpbmcsIHZlcnNpb246IG51bWJlciB9IHtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhYmFzZTogdGhpcy5kYk5hbWUsXG4gICAgICBzdG9yZTogdGhpcy5zdG9yZU5hbWUsXG4gICAgICB2ZXJzaW9uOiB0aGlzLmRiVmVyc2lvbixcbiAgICB9O1xuXG4gIH1cblxuICAvKipcbiAgICogTnVtYmVyIG9mIGl0ZW1zIGluIG91ciBgaW5kZXhlZERCYCBkYXRhYmFzZSBhbmQgb2JqZWN0IHN0b3JlXG4gICAqL1xuICBnZXQgc2l6ZSgpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuXG4gICAgLyogT3BlbiBhIHRyYW5zYWN0aW9uIGluIHJlYWQtb25seSBtb2RlICovXG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb24oJ3JlYWRvbmx5JykucGlwZShcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlLCBldmVudHMgfSA9IHRyYW5zYWN0aW9uRGF0YTtcblxuICAgICAgICAvKiBSZXF1ZXN0IHRvIGtub3cgdGhlIG51bWJlciBvZiBpdGVtcyAqL1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gc3RvcmUuY291bnQoKTtcblxuICAgICAgICAvKiBSZXR1cm4gdGhlIHJlc3VsdCAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwKCgpID0+IHJlcXVlc3QucmVzdWx0KSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgdmFsdWUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYW4gaXRlbSB2YWx1ZSBpbiBvdXIgYGluZGV4ZWREQmAgc3RvcmVcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcmV0dXJucyBUaGUgaXRlbSdzIHZhbHVlIGlmIHRoZSBrZXkgZXhpc3RzLCBgdW5kZWZpbmVkYCBvdGhlcndpc2UsIHdyYXBwZWQgaW4gYW4gUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICovXG4gIGdldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFTCoHwgdW5kZWZpbmVkPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gcmVhZC1vbmx5IG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZG9ubHknKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIFJlcXVlc3QgdGhlIHZhbHVlIHdpdGggdGhlIGtleSBwcm92aWRlZCBieSB0aGUgdXNlciAqL1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gc3RvcmUuZ2V0KGtleSk7XG5cbiAgICAgICAgLyogTGlzdGVuIGV2ZW50cyBhbmQgcmV0dXJuIHRoZSByZXN1bHQgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcCgoKSA9PiB7XG5cbiAgICAgICAgICBpZiAoKHJlcXVlc3QucmVzdWx0ICE9PSB1bmRlZmluZWQpICYmIChyZXF1ZXN0LnJlc3VsdCAhPT0gbnVsbCkpIHtcblxuICAgICAgICAgICAgLyogUHJpb3IgdG8gdjgsIHRoZSB2YWx1ZSB3YXMgd3JhcHBlZCBpbiBhbiBgeyB2YWx1ZTogLi4ufWAgb2JqZWN0ICovXG4gICAgICAgICAgICBpZiAoIXRoaXMubm9XcmFwICYmICh0eXBlb2YgcmVxdWVzdC5yZXN1bHQgPT09ICdvYmplY3QnKSAmJiAodGhpcy53cmFwSW5kZXggaW4gcmVxdWVzdC5yZXN1bHQpICYmXG4gICAgICAgICAgICAocmVxdWVzdC5yZXN1bHRbdGhpcy53cmFwSW5kZXhdICE9PSB1bmRlZmluZWQpICYmIChyZXF1ZXN0LnJlc3VsdFt0aGlzLndyYXBJbmRleF0gIT09IG51bGwpKSB7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIChyZXF1ZXN0LnJlc3VsdFt0aGlzLndyYXBJbmRleF0gYXMgVCk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgLyogQ2FzdCB0byB0aGUgd2FudGVkIHR5cGUgKi9cbiAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QucmVzdWx0IGFzIFQ7XG5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qIFJldHVybiBgdW5kZWZpbmVkYCBpZiB0aGUgdmFsdWUgaXMgZW1wdHkgKi9cbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIH0pKTtcblxuICAgICAgfSksXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlIGFmdGVyIHRoZSBmaXJzdCB2YWx1ZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhbiBpdGVtIGluIG91ciBgaW5kZXhlZERCYCBzdG9yZVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBkYXRhIFRoZSBpdGVtJ3MgdmFsdWVcbiAgICogQHJldHVybnMgQW4gUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIHNldChrZXk6IHN0cmluZywgZGF0YTogdW5rbm93bik6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICAvKiBTdG9yaW5nIGB1bmRlZmluZWRgIGluIGBpbmRleGVkRGJgIGNhbiBjYXVzZSBpc3N1ZXMgaW4gc29tZSBicm93c2VycyBzbyByZW1vdmluZyBpdGVtIGluc3RlYWQgKi9cbiAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5kZWxldGUoa2V5KTtcbiAgICB9XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gd3JpdGUgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkd3JpdGUnKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIFByaW9yIHRvIHY4LCBkYXRhIHdhcyB3cmFwcGVkIGluIGEgYHsgdmFsdWU6IC4uLiB9YCBvYmplY3QgKi9cbiAgICAgICAgY29uc3QgZGF0YVRvU3RvcmUgPSB0aGlzLm5vV3JhcCA/IGRhdGEgOiB7IFt0aGlzLndyYXBJbmRleF06IGRhdGEgfTtcblxuICAgICAgICAvKiBBZGQgaWYgdGhlIGl0ZW0gaXMgbm90IGV4aXN0aW5nIHlldCwgb3IgdXBkYXRlIG90aGVyd2lzZSAqL1xuICAgICAgICBzdG9yZS5wdXQoZGF0YVRvU3RvcmUsIGtleSk7XG5cbiAgICAgICAgLyogTGlzdGVuIHRvIGV2ZW50cyBhbmQgcmV0dXJuIGB1bmRlZmluZWRgIGFzIG5vIHZhbHVlIGlzIGV4cGVjdGVkICovXG4gICAgICAgIHJldHVybiBldmVudHMucGlwZShtYXBUbyh1bmRlZmluZWQpKTtcblxuICAgICAgfSksXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlIGFmdGVyIHRoZSBmaXJzdCB2YWx1ZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBhbiBpdGVtIGluIG91ciBgaW5kZXhlZERCYCBzdG9yZVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqL1xuICBkZWxldGUoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgLyogT3BlbiBhIHRyYW5zYWN0aW9uIGluIHdyaXRlIG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZHdyaXRlJykucGlwZShcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlLCBldmVudHMgfSA9IHRyYW5zYWN0aW9uRGF0YTtcblxuICAgICAgICAvKiBEZWxldGUgdGhlIGl0ZW0gaW4gc3RvcmUgKi9cbiAgICAgICAgc3RvcmUuZGVsZXRlKGtleSk7XG5cbiAgICAgICAgLyogTGlzdGVuIHRvIGV2ZW50cyBhbmQgcmV0dXJuIGB1bmRlZmluZWRgIGFzIG5vIGRhdGEgaXMgZXhwZWN0ZWQgaGVyZSAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwVG8odW5kZWZpbmVkKSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgdmFsdWUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYWxsIGl0ZW1zIGZyb20gb3VyIGBpbmRleGVkREJgIG9iamV0IHN0b3JlXG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqL1xuICBjbGVhcigpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgLyogT3BlbiBhIHRyYW5zYWN0aW9uIGluIHdyaXRlIG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZHdyaXRlJykucGlwZShcbiAgICAgIG1lcmdlTWFwKCh0cmFuc2FjdGlvbkRhdGEpID0+IHtcblxuICAgICAgICBjb25zdCB7IHN0b3JlLCBldmVudHMgfSA9IHRyYW5zYWN0aW9uRGF0YTtcblxuICAgICAgICAvKiBEZWxldGUgYWxsIGl0ZW1zIGluIG9iamVjdCBzdG9yZSAqL1xuICAgICAgICBzdG9yZS5jbGVhcigpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBldmVudHMgYW5kIHJldHVybiBgdW5kZWZpbmVkYCBhcyBubyBkYXRhIGlzIGV4cGVjdGVkIGhlcmUgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcFRvKHVuZGVmaW5lZCkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgdGhlIGtleXMgaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIGl0ZXJhdGluZyBvbiBlYWNoIGtleVxuICAgKi9cbiAga2V5cygpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuXG4gICAgLyogT3BlbiBhIHRyYW5zYWN0aW9uIGluIHJlYWQtb25seSBtb2RlICovXG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb24oJ3JlYWRvbmx5JykucGlwZShcbiAgICAgIC8qIGBmaXJzdCgpYCBpcyB1c2VkIGFzIHRoZSBmaW5hbCBvcGVyYXRvciBpbiBvdGhlciBtZXRob2RzIHRvIGNvbXBsZXRlIHRoZSBgT2JzZXJ2YWJsZWBcbiAgICAgICAqIChhcyBpdCBhbGwgc3RhcnRzIGZyb20gYSBgUmVwbGF5U3ViamVjdGAgd2hpY2ggbmV2ZXIgZW5kcyksXG4gICAgICAgKiBidXQgYXMgdGhpcyBtZXRob2QgaXMgaXRlcmF0aW5nIG92ZXIgbXVsdGlwbGUgdmFsdWVzLCBgZmlyc3QoKWAgKiptdXN0KiogYmUgdXNlZCBoZXJlICovXG4gICAgICBmaXJzdCgpLFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUgfSA9IHRyYW5zYWN0aW9uRGF0YTtcblxuICAgICAgICAvKiBPcGVuIGEgY3Vyc29yIG9uIHRoZSBzdG9yZVxuICAgICAgICAgKiBgLm9wZW5LZXlDdXJzb3IoKWAgaXMgYmV0dGVyIGZvciBwZXJmb3JtYW5jZSwgYnV0IG9ubHkgYXZhaWxhYmxlIGluIGluZGV4ZWREQiB2MiAobWlzc2luZyBpbiBJRS9FZGdlKVxuICAgICAgICAgKiBBdm9pZCBpc3N1ZXMgbGlrZSBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy82OSAqL1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gKCdvcGVuS2V5Q3Vyc29yJyBpbiBzdG9yZSkgPyBzdG9yZS5vcGVuS2V5Q3Vyc29yKCkgOiAoc3RvcmUgYXMgSURCT2JqZWN0U3RvcmUpLm9wZW5DdXJzb3IoKTtcblxuICAgICAgICAvKiBMaXN0ZW4gdG8gc3VjY2VzcyBldmVudCAqL1xuICAgICAgICBjb25zdCBzdWNjZXNzJCA9IGZyb21FdmVudChyZXF1ZXN0LCAnc3VjY2VzcycpLnBpcGUoXG4gICAgICAgICAgLyogU3RvcCB0aGUgYE9ic2VydmFibGVgIHdoZW4gdGhlIGN1cnNvciBpcyBgbnVsbGAgKi9cbiAgICAgICAgICB0YWtlV2hpbGUoKCkgPT4gKHJlcXVlc3QucmVzdWx0ICE9PSBudWxsKSksXG4gICAgICAgICAgLyogVGhpcyBsaWIgb25seSBhbGxvd3Mgc3RyaW5nIGtleXMsIGJ1dCB1c2VyIGNvdWxkIGhhdmUgYWRkZWQgb3RoZXIgdHlwZXMgb2Yga2V5cyBmcm9tIG91dHNpZGVcbiAgICAgICAgICAgKiBJdCdzIE9LIHRvIGNhc3QgYXMgdGhlIGN1cnNvciBhcyBiZWVuIHRlc3RlZCBpbiB0aGUgcHJldmlvdXMgb3BlcmF0b3IgKi9cbiAgICAgICAgICBtYXAoKCkgPT4gKHJlcXVlc3QucmVzdWx0IGFzIElEQkN1cnNvcikua2V5LnRvU3RyaW5nKCkpLFxuICAgICAgICAgIC8qIEl0ZXJhdGUgb24gdGhlIGN1cnNvciAqL1xuICAgICAgICAgIHRhcCgoKSA9PiB7IChyZXF1ZXN0LnJlc3VsdCBhcyBJREJDdXJzb3IpLmNvbnRpbnVlKCk7IH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBlcnJvciBldmVudCBhbmQgaWYgc28sIHRocm93IGFuIGVycm9yICovXG4gICAgICAgIGNvbnN0IGVycm9yJCA9IHRoaXMubGlzdGVuRXJyb3IocmVxdWVzdCk7XG5cbiAgICAgICAgLyogQ2hvb3NlIHRoZSBmaXJzdCBldmVudCB0byBvY2N1ciAqL1xuICAgICAgICByZXR1cm4gcmFjZShbc3VjY2VzcyQsIGVycm9yJF0pO1xuXG4gICAgICB9KSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBrZXkgZXhpc3RzIGluIG91ciBgaW5kZXhlZERCYCBzdG9yZVxuICAgKiBAcmV0dXJucyBBbiBSeEpTIGBPYnNlcnZhYmxlYCB0ZWxsaW5nIGlmIHRoZSBrZXkgZXhpc3RzIG9yIG5vdFxuICAgKi9cbiAgaGFzKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gcmVhZC1vbmx5IG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZG9ubHknKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIENoZWNrIGlmIHRoZSBrZXkgZXhpc3RzIGluIHRoZSBzdG9yZVxuICAgICAgICAgKiBgZ2V0S2V5KClgIGlzIGJldHRlciBidXQgb25seSBhdmFpbGFibGUgaW4gYGluZGV4ZWREQmAgdjIgKENocm9tZSA+PSA1OCwgbWlzc2luZyBpbiBJRS9FZGdlKS5cbiAgICAgICAgICogSW4gb2xkZXIgYnJvd3NlcnMsIHRoZSB2YWx1ZSBpcyBjaGVja2VkIGluc3RlYWQsIGJ1dCBpdCBjb3VsZCBsZWFkIHRvIGFuIGV4Y2VwdGlvblxuICAgICAgICAgKiBpZiBgdW5kZWZpbmVkYCB3YXMgc3RvcmVkIG91dHNpZGUgb2YgdGhpcyBsaWIgKGUuZy4gZGlyZWN0bHkgd2l0aCB0aGUgbmF0aXZlIGBpbmRleGVkREJgIEFQSSkuXG4gICAgICAgICAqIEZpeGVzIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzY5XG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gICgnZ2V0S2V5JyBpbiBzdG9yZSkgPyBzdG9yZS5nZXRLZXkoa2V5KSA6IChzdG9yZSBhcyBJREJPYmplY3RTdG9yZSkuZ2V0KGtleSk7XG5cbiAgICAgICAgLyogTGlzdGVuIHRvIGV2ZW50cyBhbmQgcmV0dXJuIGB0cnVlYCBvciBgZmFsc2VgICovXG4gICAgICAgIHJldHVybiBldmVudHMucGlwZShtYXAoKCkgPT4gKHJlcXVlc3QucmVzdWx0ICE9PSB1bmRlZmluZWQpID8gdHJ1ZSA6IGZhbHNlKSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogQ29ubmVjdHMgdG8gYGluZGV4ZWREQmAgYW5kIGNyZWF0ZXMgdGhlIG9iamVjdCBzdG9yZSBvbiBmaXJzdCB0aW1lXG4gICAqL1xuICBwcm90ZWN0ZWQgY29ubmVjdCgpOiB2b2lkIHtcblxuICAgIGxldCByZXF1ZXN0OiBJREJPcGVuREJSZXF1ZXN0O1xuXG4gICAgLyogQ29ubmVjdCB0byBgaW5kZXhlZERCYFxuICAgICAqIFdpbGwgZmFpbCBpbiBTYWZhcmkgY3Jvc3Mtb3JpZ2luIGlmcmFtZXNcbiAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy80Mn0gKi9cbiAgICB0cnkge1xuXG4gICAgICAvKiBEbyBOT1QgZXhwbGljaXQgYHdpbmRvd2AgaGVyZSwgYXMgYGluZGV4ZWREQmAgY291bGQgYmUgdXNlZCBmcm9tIGEgd2ViIHdvcmtlciB0b28gKi9cbiAgICAgIHJlcXVlc3QgPSBpbmRleGVkREIub3Blbih0aGlzLmRiTmFtZSwgdGhpcy5kYlZlcnNpb24pO1xuXG4gICAgfcKgY2F0Y2gge1xuXG4gICAgICB0aGlzLmRhdGFiYXNlLmVycm9yKG5ldyBJREJCcm9rZW5FcnJvcigpKTtcblxuICAgICAgcmV0dXJuO1xuXG4gICAgfVxuXG4gICAgLyogQ3JlYXRlIHN0b3JlIG9uIGZpcnN0IGNvbm5lY3Rpb24gKi9cbiAgICB0aGlzLmNyZWF0ZVN0b3JlKHJlcXVlc3QpO1xuXG4gICAgLyogTGlzdGVuIHRvIHN1Y2Nlc3MgYW5kIGVycm9yIGV2ZW50cyAqL1xuICAgIGNvbnN0IHN1Y2Nlc3MkID0gZnJvbUV2ZW50KHJlcXVlc3QsICdzdWNjZXNzJyk7XG4gICAgY29uc3QgZXJyb3IkID0gdGhpcy5saXN0ZW5FcnJvcihyZXF1ZXN0KTtcblxuICAgIC8qIENob29zZSB0aGUgZmlyc3QgdG8gb2NjdXIgKi9cbiAgICByYWNlKFtzdWNjZXNzJCwgZXJyb3IkXSlcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgKi9cbiAgICAgIC5waXBlKGZpcnN0KCkpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKCkgPT4ge1xuICAgICAgICAgIC8qIFJlZ2lzdGVyIHRoZSBkYXRhYmFzZSBjb25uZWN0aW9uIGluIHRoZSBgUmVwbGF5U3ViamVjdGAgZm9yIGZ1cnRoZXIgYWNjZXNzICovXG4gICAgICAgICAgdGhpcy5kYXRhYmFzZS5uZXh0KHJlcXVlc3QucmVzdWx0KTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICAvKiBGaXJlZm94IHByaXZhdGUgbW9kZSBpc3N1ZTogZmFsbGJhY2sgc3RvcmFnZSBpZiBJbmRleGVkRGIgY29ubmVjdGlvbiBpcyBmYWlsaW5nXG4gICAgICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD03ODE5ODJ9XG4gICAgICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy8yNn0gKi9cbiAgICAgICAgICB0aGlzLmRhdGFiYXNlLmVycm9yKG5ldyBJREJCcm9rZW5FcnJvcigpKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIHN0b3JlIG9uIGZpcnN0IHVzZSBvZiBgaW5kZXhlZERCYFxuICAgKiBAcGFyYW0gcmVxdWVzdCBgaW5kZXhlZERCYCBkYXRhYmFzZSBvcGVuaW5nIHJlcXVlc3RcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVTdG9yZShyZXF1ZXN0OiBJREJPcGVuREJSZXF1ZXN0KTogdm9pZCB7XG5cbiAgICAvKiBMaXN0ZW4gdG8gdGhlIGV2ZW50IGZpcmVkIG9uIGZpcnN0IGNvbm5lY3Rpb24gKi9cbiAgICBmcm9tRXZlbnQocmVxdWVzdCwgJ3VwZ3JhZGVuZWVkZWQnKVxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSAqL1xuICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoKSA9PiB7XG5cbiAgICAgICAgICAvKiBDaGVjayBpZiB0aGUgc3RvcmUgYWxyZWFkeSBleGlzdHMsIHRvIGF2b2lkIGVycm9yICovXG4gICAgICAgICAgaWYgKCFyZXF1ZXN0LnJlc3VsdC5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKHRoaXMuc3RvcmVOYW1lKSkge1xuXG4gICAgICAgICAgICAvKiBDcmVhdGUgdGhlIG9iamVjdCBzdG9yZSAqL1xuICAgICAgICAgICAgcmVxdWVzdC5yZXN1bHQuY3JlYXRlT2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuXG4gICAgICAgICAgfVxuXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgICogT3BlbiBhbiBgaW5kZXhlZERCYCB0cmFuc2FjdGlvbiBhbmQgZ2V0IG91ciBzdG9yZVxuICAgKiBAcGFyYW0gbW9kZSBgcmVhZG9ubHlgIG9yIGByZWFkd3JpdGVgXG4gICAqIEByZXR1cm5zIEFuIGBpbmRleGVkREJgIHRyYW5zYWN0aW9uIHN0b3JlIGFuZCBldmVudHMsIHdyYXBwZWQgaW4gYW4gUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICovXG4gIHByb3RlY3RlZCB0cmFuc2FjdGlvbihtb2RlOiBJREJUcmFuc2FjdGlvbk1vZGUpOiBPYnNlcnZhYmxlPHtcbiAgICBzdG9yZTogSURCT2JqZWN0U3RvcmU7XG4gICAgZXZlbnRzOiBPYnNlcnZhYmxlPEV2ZW50PjtcbiAgfT4ge1xuXG4gICAgLyogRnJvbSB0aGUgYGluZGV4ZWREQmAgY29ubmVjdGlvbiwgb3BlbiBhIHRyYW5zYWN0aW9uIGFuZCBnZXQgdGhlIHN0b3JlICovXG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2VcbiAgICAgIC5waXBlKG1lcmdlTWFwKChkYXRhYmFzZSkgPT4ge1xuXG4gICAgICAgIGxldCB0cmFuc2FjdGlvbjogSURCVHJhbnNhY3Rpb247XG5cbiAgICAgICAgdHJ5IHtcblxuICAgICAgICAgIHRyYW5zYWN0aW9uID0gZGF0YWJhc2UudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgbW9kZSk7XG5cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcblxuICAgICAgICAgICAgLyogVGhlIHN0b3JlIGNvdWxkIGhhdmUgYmVlbiBkZWxldGVkIGZyb20gb3V0c2lkZSAqL1xuICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoZXJyb3IgYXMgRE9NRXhjZXB0aW9uKTtcblxuICAgICAgICB9XG5cbiAgICAgICAgLyogR2V0IHRoZSBzdG9yZSBmcm9tIHRoZSB0cmFuc2FjdGlvbiAqL1xuICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcblxuICAgICAgICAvKiBMaXN0ZW4gdHJhbnNhY3Rpb24gYGNvbXBsZXRlYCBhbmQgYGVycm9yYCBldmVudHMgKi9cbiAgICAgICAgY29uc3QgZXZlbnRzID0gdGhpcy5saXN0ZW5UcmFuc2FjdGlvbkV2ZW50cyh0cmFuc2FjdGlvbik7XG5cbiAgICAgICAgcmV0dXJuIG9mKHsgc3RvcmUsIGV2ZW50cyB9KTtcblxuICAgICAgfSkpO1xuXG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuIGVycm9ycyBvbiBhIHRyYW5zYWN0aW9uIG9yIHJlcXVlc3QsIGFuZCB0aHJvdyBpZiB0cmlnZXJyZWRcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uT3JSZXF1ZXN0IGBpbmRleGVkRGJgIHRyYW5zYWN0aW9uIG9yIHJlcXVlc3QgdG8gbGlzdGVuXG4gICAqIEByZXR1cm5zIEFuIGBPYnNlcnZhYmxlYCBsaXN0ZW5pbmcgdG8gZXJyb3JzXG4gICAqL1xuICBwcm90ZWN0ZWQgbGlzdGVuRXJyb3IodHJhbnNhY3Rpb25PclJlcXVlc3Q6IElEQlRyYW5zYWN0aW9uIHwgSURCUmVxdWVzdCk6IE9ic2VydmFibGU8bmV2ZXI+IHtcblxuICAgIHJldHVybiBmcm9tRXZlbnQodHJhbnNhY3Rpb25PclJlcXVlc3QsICdlcnJvcicpLnBpcGUoXG4gICAgICAvKiBUaHJvdyBvbiBlcnJvciB0byBiZSBhYmxlIHRvIGNhdGNoIGVycm9ycyBpbiBSeEpTIHdheSAqL1xuICAgICAgbWVyZ2VNYXAoKCkgPT4gdGhyb3dFcnJvcih0cmFuc2FjdGlvbk9yUmVxdWVzdC5lcnJvcikpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0ZW4gdHJhbnNhY3Rpb24gYGNvbXBsZXRlYCBhbmQgYGVycm9yYCBldmVudHNcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uIFRyYW5zYWN0aW9uIHRvIGxpc3RlblxuICAgKiBAcmV0dXJucyBBbiBgT2JzZXJ2YWJsZWAgbGlzdGVuaW5nIHRvIHRyYW5zYWN0aW9uIGBjb21wbGV0ZWAgYW5kIGBlcnJvcmAgZXZlbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgbGlzdGVuVHJhbnNhY3Rpb25FdmVudHModHJhbnNhY3Rpb246IElEQlRyYW5zYWN0aW9uKTogT2JzZXJ2YWJsZTxFdmVudD4ge1xuXG4gICAgLyogTGlzdGVuIHRvIHRoZSBgY29tcGxldGVgIGV2ZW50ICovXG4gICAgY29uc3QgY29tcGxldGUkID0gZnJvbUV2ZW50KHRyYW5zYWN0aW9uLCAnY29tcGxldGUnKTtcblxuICAgIC8qIExpc3RlbiB0byB0aGUgYGVycm9yYCBldmVudCAqL1xuICAgIGNvbnN0IGVycm9yJCA9IHRoaXMubGlzdGVuRXJyb3IodHJhbnNhY3Rpb24pO1xuXG4gICAgLyogQ2hvb3NlIHRoZSBmaXJzdCBldmVudCB0byBvY2N1ciAqL1xuICAgIHJldHVybiByYWNlKFtjb21wbGV0ZSQsIGVycm9yJF0pO1xuXG4gIH1cblxufVxuIl19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXhlZGRiLWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9kYXRhYmFzZXMvaW5kZXhlZGRiLWRhdGFiYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWMsYUFBYSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsRixPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3RSxPQUFPLEVBQ0wsV0FBVyxFQUFFLGNBQWMsRUFBRSxzQkFBc0IsRUFBRSxjQUFjLEVBQ25FLG1CQUFtQixFQUFFLHNCQUFzQixFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFDOUUsTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7O0FBTTlDO0lBQUEsSUFBYSxpQkFBaUIsR0FBOUIsTUFBYSxpQkFBaUI7UUFpQzVCOzs7Ozs7V0FNRztRQUNILFlBQ3VCLFNBQVMsbUJBQW1CLEVBQ3pCLFlBQVksc0JBQXNCLEVBQ2xDLFlBQVksc0JBQXNCLEVBQ3JDLFNBQVMsbUJBQW1CO1lBM0JuRDs7O2VBR0c7WUFDZ0IsYUFBUSxHQUFHLElBQUksYUFBYSxDQUFjLENBQUMsQ0FBQyxDQUFDO1lBT2hFOztlQUVHO1lBQ2dCLGNBQVMsR0FBRyxPQUFPLENBQUM7WUFnQnJDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1lBQzNCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1lBQzNCLElB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QUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQ3ZELENBQUM7UUFFSixDQUFDO1FBRUQ7Ozs7V0FJRztRQUNPLHVCQUF1QixDQUFDLFdBQTJCO1lBRTNELG9DQUFvQztZQUNwQyxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRXJELGlDQUFpQztZQUNqQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRTdDLHFDQUFxQztZQUNyQyxPQUFPLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBRW5DLENBQUM7S0FFRixDQUFBOztnREF2WkksTUFBTSxTQUFDLFdBQVc7Z0RBQ2xCLE1BQU0sU0FBQyxjQUFjO2dEQUNyQixNQUFNLFNBQUMsY0FBYztnREFDckIsTUFBTSxTQUFDLFdBQVc7OztJQTVDVixpQkFBaUI7UUFIN0IsVUFBVSxDQUFDO1lBQ1YsVUFBVSxFQUFFLE1BQU07U0FDbkIsQ0FBQztRQTBDRyxXQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUNuQixXQUFBLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQTtRQUN0QixXQUFBLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQTtRQUN0QixXQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQTtPQTVDWCxpQkFBaUIsQ0FnYzdCOzRCQTljRDtLQThjQztTQWhjWSxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFJlcGxheVN1YmplY3QsIGZyb21FdmVudCwgb2YsIHRocm93RXJyb3IsIHJhY2UgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgbWVyZ2VNYXAsIGZpcnN0LCB0YWtlV2hpbGUsIHRhcCwgbWFwVG8gfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIElEQl9EQl9OQU1FLCBJREJfU1RPUkVfTkFNRSwgREVGQVVMVF9JREJfU1RPUkVfTkFNRSwgSURCX0RCX1ZFUlNJT04sXG4gIERFRkFVTFRfSURCX0RCX05BTUUsIERFRkFVTFRfSURCX0RCX1ZFUlNJT04sIElEQl9OT19XUkFQLCBERUZBVUxUX0lEQl9OT19XUkFQXG59IGZyb20gJy4uL3Rva2Vucyc7XG5pbXBvcnQgeyBJREJCcm9rZW5FcnJvciB9IGZyb20gJy4vZXhjZXB0aW9ucyc7XG5pbXBvcnQgeyBMb2NhbERhdGFiYXNlIH0gZnJvbSAnLi9sb2NhbC1kYXRhYmFzZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEluZGV4ZWREQkRhdGFiYXNlIGltcGxlbWVudHMgTG9jYWxEYXRhYmFzZSB7XG5cbiAgLyoqXG4gICAqIGBpbmRleGVkREJgIGRhdGFiYXNlIG5hbWVcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBkYk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogYGluZGV4ZWREQmAgb2JqZWN0IHN0b3JlIG5hbWVcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBzdG9yZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogYGluZGV4ZWREQmAgZGF0YWJhc2UgdmVyc2lvbi4gTXVzdCBiZSBhbiB1bnNpZ25lZCAqKmludGVnZXIqKlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRiVmVyc2lvbjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBgaW5kZXhlZERCYCBkYXRhYmFzZSBjb25uZWN0aW9uLCB3cmFwcGVkIGluIGEgUnhKUyBgUmVwbGF5U3ViamVjdGAgdG8gYmUgYWJsZSB0byBhY2Nlc3MgdGhlIGNvbm5lY3Rpb25cbiAgICogZXZlbiBhZnRlciB0aGUgY29ubmVjdGlvbiBzdWNjZXNzIGV2ZW50IGhhcHBlbmVkXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGF0YWJhc2UgPSBuZXcgUmVwbGF5U3ViamVjdDxJREJEYXRhYmFzZT4oMSk7XG5cbiAgLyoqXG4gICAqIEZsYWcgdG8gbm90IHdyYXAgYGluZGV4ZWREQmAgdmFsdWVzIGZvciBpbnRlcm9wZXJhYmlsaXR5IG9yIHRvIHdyYXAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbm9XcmFwOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmRleCB1c2VkIHdoZW4gd3JhcHBpbmcgdmFsdWUuICpGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBvbmx5LipcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSB3cmFwSW5kZXggPSAndmFsdWUnO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvciBwYXJhbXMgYXJlIHByb3ZpZGVkIGJ5IEFuZ3VsYXIgKGJ1dCBjYW4gYWxzbyBiZSBwYXNzZWQgbWFudWFsbHkgaW4gdGVzdHMpXG4gICAqIEBwYXJhbSBkYk5hbWUgYGluZGV4ZWREQmAgZGF0YWJhc2UgbmFtZVxuICAgKiBAcGFyYW0gc3RvcmVOYW1lIGBpbmRleGVkREJgIHN0b3JlIG5hbWVcbiAgICogQHBhcmFtIGRiVmVyc2lvbiBgaW5kZXhlZERCYCBkYXRhYmFzZSB2ZXJzaW9uXG4gICAqIEBwYXJhbSBub1dyYXAgRmxhZyB0byBub3Qgd3JhcCBgaW5kZXhlZERCYCB2YWx1ZXMgZm9yIGludGVyb3BlcmFiaWxpdHkgb3IgdG8gd3JhcCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChJREJfREJfTkFNRSkgZGJOYW1lID0gREVGQVVMVF9JREJfREJfTkFNRSxcbiAgICBASW5qZWN0KElEQl9TVE9SRV9OQU1FKSBzdG9yZU5hbWUgPSBERUZBVUxUX0lEQl9TVE9SRV9OQU1FLFxuICAgIEBJbmplY3QoSURCX0RCX1ZFUlNJT04pIGRiVmVyc2lvbiA9IERFRkFVTFRfSURCX0RCX1ZFUlNJT04sXG4gICAgQEluamVjdChJREJfTk9fV1JBUCkgbm9XcmFwID0gREVGQVVMVF9JREJfTk9fV1JBUCxcbiAgKSB7XG5cbiAgICB0aGlzLmRiTmFtZSA9IGRiTmFtZTtcbiAgICB0aGlzLnN0b3JlTmFtZSA9IHN0b3JlTmFtZTtcbiAgICB0aGlzLmRiVmVyc2lvbiA9IGRiVmVyc2lvbjtcbiAgICB0aGlzLm5vV3JhcCA9IG5vV3JhcDtcblxuICAgIC8qIENvbm5lY3QgdG8gYGluZGV4ZWREQmAsIHdpdGggcHJlZml4IGlmIHByb3ZpZGVkIGJ5IHRoZSB1c2VyICovXG4gICAgdGhpcy5jb25uZWN0KCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBJbmZvcm1hdGlvbiBhYm91dCBgaW5kZXhlZERCYCBjb25uZWN0aW9uLiAqT25seSB1c2VmdWwgZm9yIGludGVyb3BlcmFiaWxpdHkuKlxuICAgKiBAcmV0dXJucyBgaW5kZXhlZERCYCBkYXRhYmFzZSBuYW1lLCBzdG9yZSBuYW1lIGFuZCBkYXRhYmFzZSB2ZXJzaW9uXG4gICAqL1xuICBnZXQgYmFja2luZ1N0b3JlKCk6IHsgZGF0YWJhc2U6IHN0cmluZywgc3RvcmU6IHN0cmluZywgdmVyc2lvbjogbnVtYmVyIH0ge1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGFiYXNlOiB0aGlzLmRiTmFtZSxcbiAgICAgIHN0b3JlOiB0aGlzLnN0b3JlTmFtZSxcbiAgICAgIHZlcnNpb246IHRoaXMuZGJWZXJzaW9uLFxuICAgIH07XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaXRlbXMgaW4gb3VyIGBpbmRleGVkREJgIGRhdGFiYXNlIGFuZCBvYmplY3Qgc3RvcmVcbiAgICovXG4gIGdldCBzaXplKCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gcmVhZC1vbmx5IG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZG9ubHknKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIFJlcXVlc3QgdG8ga25vdyB0aGUgbnVtYmVyIG9mIGl0ZW1zICovXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5jb3VudCgpO1xuXG4gICAgICAgIC8qIFJldHVybiB0aGUgcmVzdWx0ICovXG4gICAgICAgIHJldHVybiBldmVudHMucGlwZShtYXAoKCkgPT4gcmVxdWVzdC5yZXN1bHQpKTtcblxuICAgICAgfSksXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlIGFmdGVyIHRoZSBmaXJzdCB2YWx1ZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogR2V0cyBhbiBpdGVtIHZhbHVlIGluIG91ciBgaW5kZXhlZERCYCBzdG9yZVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEByZXR1cm5zIFRoZSBpdGVtJ3MgdmFsdWUgaWYgdGhlIGtleSBleGlzdHMsIGB1bmRlZmluZWRgIG90aGVyd2lzZSwgd3JhcHBlZCBpbiBhbiBSeEpTIGBPYnNlcnZhYmxlYFxuICAgKi9cbiAgZ2V0PFQgPSB1bmtub3duPihrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8VMKgfCB1bmRlZmluZWQ+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogUmVxdWVzdCB0aGUgdmFsdWUgd2l0aCB0aGUga2V5IHByb3ZpZGVkIGJ5IHRoZSB1c2VyICovXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5nZXQoa2V5KTtcblxuICAgICAgICAvKiBMaXN0ZW4gZXZlbnRzIGFuZCByZXR1cm4gdGhlIHJlc3VsdCAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwKCgpID0+IHtcblxuICAgICAgICAgIGlmICgocmVxdWVzdC5yZXN1bHQgIT09IHVuZGVmaW5lZCkgJiYgKHJlcXVlc3QucmVzdWx0ICE9PSBudWxsKSkge1xuXG4gICAgICAgICAgICAvKiBQcmlvciB0byB2OCwgdGhlIHZhbHVlIHdhcyB3cmFwcGVkIGluIGFuIGB7IHZhbHVlOiAuLi59YCBvYmplY3QgKi9cbiAgICAgICAgICAgIGlmICghdGhpcy5ub1dyYXAgJiYgKHR5cGVvZiByZXF1ZXN0LnJlc3VsdCA9PT0gJ29iamVjdCcpICYmICh0aGlzLndyYXBJbmRleCBpbiByZXF1ZXN0LnJlc3VsdCkgJiZcbiAgICAgICAgICAgIChyZXF1ZXN0LnJlc3VsdFt0aGlzLndyYXBJbmRleF0gIT09IHVuZGVmaW5lZCkgJiYgKHJlcXVlc3QucmVzdWx0W3RoaXMud3JhcEluZGV4XSAhPT0gbnVsbCkpIHtcblxuICAgICAgICAgICAgICByZXR1cm4gKHJlcXVlc3QucmVzdWx0W3RoaXMud3JhcEluZGV4XSBhcyBUKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAvKiBDYXN0IHRvIHRoZSB3YW50ZWQgdHlwZSAqL1xuICAgICAgICAgICAgICByZXR1cm4gcmVxdWVzdC5yZXN1bHQgYXMgVDtcblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyogUmV0dXJuIGB1bmRlZmluZWRgIGlmIHRoZSB2YWx1ZSBpcyBlbXB0eSAqL1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgfSkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgYWZ0ZXIgdGhlIGZpcnN0IHZhbHVlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFuIGl0ZW0gaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHBhcmFtIGRhdGEgVGhlIGl0ZW0ncyB2YWx1ZVxuICAgKiBAcmV0dXJucyBBbiBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgc2V0KGtleTogc3RyaW5nLCBkYXRhOiB1bmtub3duKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIC8qIFN0b3JpbmcgYHVuZGVmaW5lZGAgaW4gYGluZGV4ZWREYmAgY2FuIGNhdXNlIGlzc3VlcyBpbiBzb21lIGJyb3dzZXJzIHNvIHJlbW92aW5nIGl0ZW0gaW5zdGVhZCAqL1xuICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlbGV0ZShrZXkpO1xuICAgIH1cblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiB3cml0ZSBtb2RlICovXG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb24oJ3JlYWR3cml0ZScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogUHJpb3IgdG8gdjgsIGRhdGEgd2FzIHdyYXBwZWQgaW4gYSBgeyB2YWx1ZTogLi4uIH1gIG9iamVjdCAqL1xuICAgICAgICBjb25zdCBkYXRhVG9TdG9yZSA9IHRoaXMubm9XcmFwID8gZGF0YSA6IHsgW3RoaXMud3JhcEluZGV4XTogZGF0YSB9O1xuXG4gICAgICAgIC8qIEFkZCBpZiB0aGUgaXRlbSBpcyBub3QgZXhpc3RpbmcgeWV0LCBvciB1cGRhdGUgb3RoZXJ3aXNlICovXG4gICAgICAgIHN0b3JlLnB1dChkYXRhVG9TdG9yZSwga2V5KTtcblxuICAgICAgICAvKiBMaXN0ZW4gdG8gZXZlbnRzIGFuZCByZXR1cm4gYHVuZGVmaW5lZGAgYXMgbm8gdmFsdWUgaXMgZXhwZWN0ZWQgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcFRvKHVuZGVmaW5lZCkpO1xuXG4gICAgICB9KSxcbiAgICAgIC8qIFRoZSBvYnNlcnZhYmxlIHdpbGwgY29tcGxldGUgYWZ0ZXIgdGhlIGZpcnN0IHZhbHVlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIGl0ZW0gaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQW4gUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gd3JpdGUgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkd3JpdGUnKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIERlbGV0ZSB0aGUgaXRlbSBpbiBzdG9yZSAqL1xuICAgICAgICBzdG9yZS5kZWxldGUoa2V5KTtcblxuICAgICAgICAvKiBMaXN0ZW4gdG8gZXZlbnRzIGFuZCByZXR1cm4gYHVuZGVmaW5lZGAgYXMgbm8gZGF0YSBpcyBleHBlY3RlZCBoZXJlICovXG4gICAgICAgIHJldHVybiBldmVudHMucGlwZShtYXBUbyh1bmRlZmluZWQpKTtcblxuICAgICAgfSksXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlIGFmdGVyIHRoZSBmaXJzdCB2YWx1ZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBhbGwgaXRlbXMgZnJvbSBvdXIgYGluZGV4ZWREQmAgb2JqZXQgc3RvcmVcbiAgICogQHJldHVybnMgQW4gUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIGNsZWFyKCk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gd3JpdGUgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkd3JpdGUnKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKHRyYW5zYWN0aW9uRGF0YSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHsgc3RvcmUsIGV2ZW50cyB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIERlbGV0ZSBhbGwgaXRlbXMgaW4gb2JqZWN0IHN0b3JlICovXG4gICAgICAgIHN0b3JlLmNsZWFyKCk7XG5cbiAgICAgICAgLyogTGlzdGVuIHRvIGV2ZW50cyBhbmQgcmV0dXJuIGB1bmRlZmluZWRgIGFzIG5vIGRhdGEgaXMgZXhwZWN0ZWQgaGVyZSAqL1xuICAgICAgICByZXR1cm4gZXZlbnRzLnBpcGUobWFwVG8odW5kZWZpbmVkKSk7XG5cbiAgICAgIH0pLFxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSAqL1xuICAgICAgZmlyc3QoKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCB0aGUga2V5cyBpbiBvdXIgYGluZGV4ZWREQmAgc3RvcmVcbiAgICogQHJldHVybnMgQW4gUnhKUyBgT2JzZXJ2YWJsZWAgaXRlcmF0aW5nIG9uIGVhY2gga2V5XG4gICAqL1xuICBrZXlzKCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG5cbiAgICAvKiBPcGVuIGEgdHJhbnNhY3Rpb24gaW4gcmVhZC1vbmx5IG1vZGUgKi9cbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbigncmVhZG9ubHknKS5waXBlKFxuICAgICAgLyogYGZpcnN0KClgIGlzIHVzZWQgYXMgdGhlIGZpbmFsIG9wZXJhdG9yIGluIG90aGVyIG1ldGhvZHMgdG8gY29tcGxldGUgdGhlIGBPYnNlcnZhYmxlYFxuICAgICAgICogKGFzIGl0IGFsbCBzdGFydHMgZnJvbSBhIGBSZXBsYXlTdWJqZWN0YCB3aGljaCBuZXZlciBlbmRzKSxcbiAgICAgICAqIGJ1dCBhcyB0aGlzIG1ldGhvZCBpcyBpdGVyYXRpbmcgb3ZlciBtdWx0aXBsZSB2YWx1ZXMsIGBmaXJzdCgpYCAqKm11c3QqKiBiZSB1c2VkIGhlcmUgKi9cbiAgICAgIGZpcnN0KCksXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSB9ID0gdHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgICAgIC8qIE9wZW4gYSBjdXJzb3Igb24gdGhlIHN0b3JlXG4gICAgICAgICAqIGAub3BlbktleUN1cnNvcigpYCBpcyBiZXR0ZXIgZm9yIHBlcmZvcm1hbmNlLCBidXQgb25seSBhdmFpbGFibGUgaW4gaW5kZXhlZERCIHYyIChtaXNzaW5nIGluIElFL0VkZ2UpXG4gICAgICAgICAqIEF2b2lkIGlzc3VlcyBsaWtlIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzY5ICovXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSAoJ29wZW5LZXlDdXJzb3InIGluIHN0b3JlKSA/IHN0b3JlLm9wZW5LZXlDdXJzb3IoKSA6IChzdG9yZSBhcyBJREJPYmplY3RTdG9yZSkub3BlbkN1cnNvcigpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0byBzdWNjZXNzIGV2ZW50ICovXG4gICAgICAgIGNvbnN0IHN1Y2Nlc3MkID0gZnJvbUV2ZW50KHJlcXVlc3QsICdzdWNjZXNzJykucGlwZShcbiAgICAgICAgICAvKiBTdG9wIHRoZSBgT2JzZXJ2YWJsZWAgd2hlbiB0aGUgY3Vyc29yIGlzIGBudWxsYCAqL1xuICAgICAgICAgIHRha2VXaGlsZSgoKSA9PiAocmVxdWVzdC5yZXN1bHQgIT09IG51bGwpKSxcbiAgICAgICAgICAvKiBUaGlzIGxpYiBvbmx5IGFsbG93cyBzdHJpbmcga2V5cywgYnV0IHVzZXIgY291bGQgaGF2ZSBhZGRlZCBvdGhlciB0eXBlcyBvZiBrZXlzIGZyb20gb3V0c2lkZVxuICAgICAgICAgICAqIEl0J3MgT0sgdG8gY2FzdCBhcyB0aGUgY3Vyc29yIGFzIGJlZW4gdGVzdGVkIGluIHRoZSBwcmV2aW91cyBvcGVyYXRvciAqL1xuICAgICAgICAgIG1hcCgoKSA9PiAocmVxdWVzdC5yZXN1bHQgYXMgSURCQ3Vyc29yKS5rZXkudG9TdHJpbmcoKSksXG4gICAgICAgICAgLyogSXRlcmF0ZSBvbiB0aGUgY3Vyc29yICovXG4gICAgICAgICAgdGFwKCgpID0+IHsgKHJlcXVlc3QucmVzdWx0IGFzIElEQkN1cnNvcikuY29udGludWUoKTsgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgLyogTGlzdGVuIHRvIGVycm9yIGV2ZW50IGFuZCBpZiBzbywgdGhyb3cgYW4gZXJyb3IgKi9cbiAgICAgICAgY29uc3QgZXJyb3IkID0gdGhpcy5saXN0ZW5FcnJvcihyZXF1ZXN0KTtcblxuICAgICAgICAvKiBDaG9vc2UgdGhlIGZpcnN0IGV2ZW50IHRvIG9jY3VyICovXG4gICAgICAgIHJldHVybiByYWNlKFtzdWNjZXNzJCwgZXJyb3IkXSk7XG5cbiAgICAgIH0pLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGtleSBleGlzdHMgaW4gb3VyIGBpbmRleGVkREJgIHN0b3JlXG4gICAqIEByZXR1cm5zIEFuIFJ4SlMgYE9ic2VydmFibGVgIHRlbGxpbmcgaWYgdGhlIGtleSBleGlzdHMgb3Igbm90XG4gICAqL1xuICBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIC8qIE9wZW4gYSB0cmFuc2FjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSAqL1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uKCdyZWFkb25seScpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgodHJhbnNhY3Rpb25EYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeyBzdG9yZSwgZXZlbnRzIH0gPSB0cmFuc2FjdGlvbkRhdGE7XG5cbiAgICAgICAgLyogQ2hlY2sgaWYgdGhlIGtleSBleGlzdHMgaW4gdGhlIHN0b3JlXG4gICAgICAgICAqIGBnZXRLZXkoKWAgaXMgYmV0dGVyIGJ1dCBvbmx5IGF2YWlsYWJsZSBpbiBgaW5kZXhlZERCYCB2MiAoQ2hyb21lID49IDU4LCBtaXNzaW5nIGluIElFL0VkZ2UpLlxuICAgICAgICAgKiBJbiBvbGRlciBicm93c2VycywgdGhlIHZhbHVlIGlzIGNoZWNrZWQgaW5zdGVhZCwgYnV0IGl0IGNvdWxkIGxlYWQgdG8gYW4gZXhjZXB0aW9uXG4gICAgICAgICAqIGlmIGB1bmRlZmluZWRgIHdhcyBzdG9yZWQgb3V0c2lkZSBvZiB0aGlzIGxpYiAoZS5nLiBkaXJlY3RseSB3aXRoIHRoZSBuYXRpdmUgYGluZGV4ZWREQmAgQVBJKS5cbiAgICAgICAgICogRml4ZXMgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvNjlcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSAgKCdnZXRLZXknIGluIHN0b3JlKSA/IHN0b3JlLmdldEtleShrZXkpIDogKHN0b3JlIGFzIElEQk9iamVjdFN0b3JlKS5nZXQoa2V5KTtcblxuICAgICAgICAvKiBMaXN0ZW4gdG8gZXZlbnRzIGFuZCByZXR1cm4gYHRydWVgIG9yIGBmYWxzZWAgKi9cbiAgICAgICAgcmV0dXJuIGV2ZW50cy5waXBlKG1hcCgoKSA9PiAocmVxdWVzdC5yZXN1bHQgIT09IHVuZGVmaW5lZCkgPyB0cnVlIDogZmFsc2UpKTtcblxuICAgICAgfSksXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlICovXG4gICAgICBmaXJzdCgpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25uZWN0cyB0byBgaW5kZXhlZERCYCBhbmQgY3JlYXRlcyB0aGUgb2JqZWN0IHN0b3JlIG9uIGZpcnN0IHRpbWVcbiAgICovXG4gIHByb3RlY3RlZCBjb25uZWN0KCk6IHZvaWQge1xuXG4gICAgbGV0IHJlcXVlc3Q6IElEQk9wZW5EQlJlcXVlc3Q7XG5cbiAgICAvKiBDb25uZWN0IHRvIGBpbmRleGVkREJgXG4gICAgICogV2lsbCBmYWlsIGluIFNhZmFyaSBjcm9zcy1vcmlnaW4gaWZyYW1lc1xuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzQyfSAqL1xuICAgIHRyeSB7XG5cbiAgICAgIC8qIERvIE5PVCBleHBsaWNpdCBgd2luZG93YCBoZXJlLCBhcyBgaW5kZXhlZERCYCBjb3VsZCBiZSB1c2VkIGZyb20gYSB3ZWIgd29ya2VyIHRvbyAqL1xuICAgICAgcmVxdWVzdCA9IGluZGV4ZWREQi5vcGVuKHRoaXMuZGJOYW1lLCB0aGlzLmRiVmVyc2lvbik7XG5cbiAgICB9wqBjYXRjaCB7XG5cbiAgICAgIHRoaXMuZGF0YWJhc2UuZXJyb3IobmV3IElEQkJyb2tlbkVycm9yKCkpO1xuXG4gICAgICByZXR1cm47XG5cbiAgICB9XG5cbiAgICAvKiBDcmVhdGUgc3RvcmUgb24gZmlyc3QgY29ubmVjdGlvbiAqL1xuICAgIHRoaXMuY3JlYXRlU3RvcmUocmVxdWVzdCk7XG5cbiAgICAvKiBMaXN0ZW4gdG8gc3VjY2VzcyBhbmQgZXJyb3IgZXZlbnRzICovXG4gICAgY29uc3Qgc3VjY2VzcyQgPSBmcm9tRXZlbnQocmVxdWVzdCwgJ3N1Y2Nlc3MnKTtcbiAgICBjb25zdCBlcnJvciQgPSB0aGlzLmxpc3RlbkVycm9yKHJlcXVlc3QpO1xuXG4gICAgLyogQ2hvb3NlIHRoZSBmaXJzdCB0byBvY2N1ciAqL1xuICAgIHJhY2UoW3N1Y2Nlc3MkLCBlcnJvciRdKVxuICAgICAgLyogVGhlIG9ic2VydmFibGUgd2lsbCBjb21wbGV0ZSAqL1xuICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoKSA9PiB7XG4gICAgICAgICAgLyogUmVnaXN0ZXIgdGhlIGRhdGFiYXNlIGNvbm5lY3Rpb24gaW4gdGhlIGBSZXBsYXlTdWJqZWN0YCBmb3IgZnVydGhlciBhY2Nlc3MgKi9cbiAgICAgICAgICB0aGlzLmRhdGFiYXNlLm5leHQocmVxdWVzdC5yZXN1bHQpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgIC8qIEZpcmVmb3ggcHJpdmF0ZSBtb2RlIGlzc3VlOiBmYWxsYmFjayBzdG9yYWdlIGlmIEluZGV4ZWREYiBjb25uZWN0aW9uIGlzIGZhaWxpbmdcbiAgICAgICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTc4MTk4Mn1cbiAgICAgICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzI2fSAqL1xuICAgICAgICAgIHRoaXMuZGF0YWJhc2UuZXJyb3IobmV3IElEQkJyb2tlbkVycm9yKCkpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgc3RvcmUgb24gZmlyc3QgdXNlIG9mIGBpbmRleGVkREJgXG4gICAqIEBwYXJhbSByZXF1ZXN0IGBpbmRleGVkREJgIGRhdGFiYXNlIG9wZW5pbmcgcmVxdWVzdFxuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZVN0b3JlKHJlcXVlc3Q6IElEQk9wZW5EQlJlcXVlc3QpOiB2b2lkIHtcblxuICAgIC8qIExpc3RlbiB0byB0aGUgZXZlbnQgZmlyZWQgb24gZmlyc3QgY29ubmVjdGlvbiAqL1xuICAgIGZyb21FdmVudChyZXF1ZXN0LCAndXBncmFkZW5lZWRlZCcpXG4gICAgICAvKiBUaGUgb2JzZXJ2YWJsZSB3aWxsIGNvbXBsZXRlICovXG4gICAgICAucGlwZShmaXJzdCgpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICgpID0+IHtcblxuICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSBzdG9yZSBhbHJlYWR5IGV4aXN0cywgdG8gYXZvaWQgZXJyb3IgKi9cbiAgICAgICAgICBpZiAoIXJlcXVlc3QucmVzdWx0Lm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnModGhpcy5zdG9yZU5hbWUpKSB7XG5cbiAgICAgICAgICAgIC8qIENyZWF0ZSB0aGUgb2JqZWN0IHN0b3JlICovXG4gICAgICAgICAgICByZXF1ZXN0LnJlc3VsdC5jcmVhdGVPYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVuIGFuIGBpbmRleGVkREJgIHRyYW5zYWN0aW9uIGFuZCBnZXQgb3VyIHN0b3JlXG4gICAqIEBwYXJhbSBtb2RlIGByZWFkb25seWAgb3IgYHJlYWR3cml0ZWBcbiAgICogQHJldHVybnMgQW4gYGluZGV4ZWREQmAgdHJhbnNhY3Rpb24gc3RvcmUgYW5kIGV2ZW50cywgd3JhcHBlZCBpbiBhbiBSeEpTIGBPYnNlcnZhYmxlYFxuICAgKi9cbiAgcHJvdGVjdGVkIHRyYW5zYWN0aW9uKG1vZGU6IElEQlRyYW5zYWN0aW9uTW9kZSk6IE9ic2VydmFibGU8e1xuICAgIHN0b3JlOiBJREJPYmplY3RTdG9yZTtcbiAgICBldmVudHM6IE9ic2VydmFibGU8RXZlbnQ+O1xuICB9PiB7XG5cbiAgICAvKiBGcm9tIHRoZSBgaW5kZXhlZERCYCBjb25uZWN0aW9uLCBvcGVuIGEgdHJhbnNhY3Rpb24gYW5kIGdldCB0aGUgc3RvcmUgKi9cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZVxuICAgICAgLnBpcGUobWVyZ2VNYXAoKGRhdGFiYXNlKSA9PiB7XG5cbiAgICAgICAgbGV0IHRyYW5zYWN0aW9uOiBJREJUcmFuc2FjdGlvbjtcblxuICAgICAgICB0cnkge1xuXG4gICAgICAgICAgdHJhbnNhY3Rpb24gPSBkYXRhYmFzZS50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCBtb2RlKTtcblxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuXG4gICAgICAgICAgICAvKiBUaGUgc3RvcmUgY291bGQgaGF2ZSBiZWVuIGRlbGV0ZWQgZnJvbSBvdXRzaWRlICovXG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvciBhcyBET01FeGNlcHRpb24pO1xuXG4gICAgICAgIH1cblxuICAgICAgICAvKiBHZXQgdGhlIHN0b3JlIGZyb20gdGhlIHRyYW5zYWN0aW9uICovXG4gICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuXG4gICAgICAgIC8qIExpc3RlbiB0cmFuc2FjdGlvbiBgY29tcGxldGVgIGFuZCBgZXJyb3JgIGV2ZW50cyAqL1xuICAgICAgICBjb25zdCBldmVudHMgPSB0aGlzLmxpc3RlblRyYW5zYWN0aW9uRXZlbnRzKHRyYW5zYWN0aW9uKTtcblxuICAgICAgICByZXR1cm4gb2YoeyBzdG9yZSwgZXZlbnRzIH0pO1xuXG4gICAgICB9KSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0ZW4gZXJyb3JzIG9uIGEgdHJhbnNhY3Rpb24gb3IgcmVxdWVzdCwgYW5kIHRocm93IGlmIHRyaWdlcnJlZFxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25PclJlcXVlc3QgYGluZGV4ZWREYmAgdHJhbnNhY3Rpb24gb3IgcmVxdWVzdCB0byBsaXN0ZW5cbiAgICogQHJldHVybnMgQW4gYE9ic2VydmFibGVgIGxpc3RlbmluZyB0byBlcnJvcnNcbiAgICovXG4gIHByb3RlY3RlZCBsaXN0ZW5FcnJvcih0cmFuc2FjdGlvbk9yUmVxdWVzdDogSURCVHJhbnNhY3Rpb24gfCBJREJSZXF1ZXN0KTogT2JzZXJ2YWJsZTxuZXZlcj4ge1xuXG4gICAgcmV0dXJuIGZyb21FdmVudCh0cmFuc2FjdGlvbk9yUmVxdWVzdCwgJ2Vycm9yJykucGlwZShcbiAgICAgIC8qIFRocm93IG9uIGVycm9yIHRvIGJlIGFibGUgdG8gY2F0Y2ggZXJyb3JzIGluIFJ4SlMgd2F5ICovXG4gICAgICBtZXJnZU1hcCgoKSA9PiB0aHJvd0Vycm9yKHRyYW5zYWN0aW9uT3JSZXF1ZXN0LmVycm9yKSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIExpc3RlbiB0cmFuc2FjdGlvbiBgY29tcGxldGVgIGFuZCBgZXJyb3JgIGV2ZW50c1xuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb24gVHJhbnNhY3Rpb24gdG8gbGlzdGVuXG4gICAqIEByZXR1cm5zIEFuIGBPYnNlcnZhYmxlYCBsaXN0ZW5pbmcgdG8gdHJhbnNhY3Rpb24gYGNvbXBsZXRlYCBhbmQgYGVycm9yYCBldmVudHNcbiAgICovXG4gIHByb3RlY3RlZCBsaXN0ZW5UcmFuc2FjdGlvbkV2ZW50cyh0cmFuc2FjdGlvbjogSURCVHJhbnNhY3Rpb24pOiBPYnNlcnZhYmxlPEV2ZW50PiB7XG5cbiAgICAvKiBMaXN0ZW4gdG8gdGhlIGBjb21wbGV0ZWAgZXZlbnQgKi9cbiAgICBjb25zdCBjb21wbGV0ZSQgPSBmcm9tRXZlbnQodHJhbnNhY3Rpb24sICdjb21wbGV0ZScpO1xuXG4gICAgLyogTGlzdGVuIHRvIHRoZSBgZXJyb3JgIGV2ZW50ICovXG4gICAgY29uc3QgZXJyb3IkID0gdGhpcy5saXN0ZW5FcnJvcih0cmFuc2FjdGlvbik7XG5cbiAgICAvKiBDaG9vc2UgdGhlIGZpcnN0IGV2ZW50IHRvIG9jY3VyICovXG4gICAgcmV0dXJuIHJhY2UoW2NvbXBsZXRlJCwgZXJyb3IkXSk7XG5cbiAgfVxuXG59XG4iXX0=

@@ -61,20 +61,23 @@ import { __decorate } from "tslib";

}
let LocalDatabase = class LocalDatabase {
};
LocalDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalDatabase_Factory() { return localDatabaseFactory(i0.ɵɵinject(i0.PLATFORM_ID), i0.ɵɵinject(i1.LS_PREFIX), i0.ɵɵinject(i1.IDB_DB_NAME), i0.ɵɵinject(i1.IDB_STORE_NAME), i0.ɵɵinject(i1.IDB_DB_VERSION), i0.ɵɵinject(i1.IDB_NO_WRAP)); }, token: LocalDatabase, providedIn: "root" });
LocalDatabase = __decorate([
Injectable({
providedIn: 'root',
useFactory: localDatabaseFactory,
deps: [
PLATFORM_ID,
LS_PREFIX,
IDB_DB_NAME,
IDB_STORE_NAME,
IDB_DB_VERSION,
IDB_NO_WRAP,
]
})
], LocalDatabase);
let LocalDatabase = /** @class */ (() => {
let LocalDatabase = class LocalDatabase {
};
LocalDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalDatabase_Factory() { return localDatabaseFactory(i0.ɵɵinject(i0.PLATFORM_ID), i0.ɵɵinject(i1.LS_PREFIX), i0.ɵɵinject(i1.IDB_DB_NAME), i0.ɵɵinject(i1.IDB_STORE_NAME), i0.ɵɵinject(i1.IDB_DB_VERSION), i0.ɵɵinject(i1.IDB_NO_WRAP)); }, token: LocalDatabase, providedIn: "root" });
LocalDatabase = __decorate([
Injectable({
providedIn: 'root',
useFactory: localDatabaseFactory,
deps: [
PLATFORM_ID,
LS_PREFIX,
IDB_DB_NAME,
IDB_STORE_NAME,
IDB_DB_VERSION,
IDB_NO_WRAP,
]
})
], LocalDatabase);
return LocalDatabase;
})();
export { LocalDatabase };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtZGF0YWJhc2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LXB3YS9sb2NhbC1zdG9yYWdlLyIsInNvdXJjZXMiOlsibGliL2RhdGFiYXNlcy9sb2NhbC1kYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDeEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDaEcsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7QUFFbkQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FDbEMsVUFBa0IsRUFBRSxRQUFnQixFQUFFLFNBQWlCLEVBQUUsWUFBb0IsRUFDN0UsWUFBb0IsRUFBRSxTQUFrQjtJQUV4Qzs7O09BR0c7SUFDSCxJQUFJO1FBRUYscUZBQXFGO1FBQ3JGLElBQUksaUJBQWlCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksU0FBUyxDQUFDLEVBQUU7WUFFL0c7Ozs7Ozs7cUhBT3lHO1lBQ3pHLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUVoRjthQUFNLElBQUksaUJBQWlCLENBQUMsVUFBVSxDQUFDO2VBQ3JDLENBQUMsWUFBWSxLQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLFlBQVksQ0FBQyxFQUFFO1lBRXpGOzs7Ozs7Ozs7OztjQVdFO1lBQ0YsT0FBTyxJQUFJLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBRTNDO0tBRUY7SUFBQyxXQUFNLEdBQUU7SUFFVjs7OztPQUlHO0lBQ0gsT0FBTyxJQUFJLGNBQWMsRUFBRSxDQUFDO0FBRTlCLENBQUM7QUFjRCxJQUFzQixhQUFhLEdBQW5DLE1BQXNCLGFBQWE7Q0FXbEMsQ0FBQTs7QUFYcUIsYUFBYTtJQVpsQyxVQUFVLENBQUM7UUFDVixVQUFVLEVBQUUsTUFBTTtRQUNsQixVQUFVLEVBQUUsb0JBQW9CO1FBQ2hDLElBQUksRUFBRTtZQUNKLFdBQVc7WUFDWCxTQUFTO1lBQ1QsV0FBVztZQUNYLGNBQWM7WUFDZCxjQUFjO1lBQ2QsV0FBVztTQUNaO0tBQ0YsQ0FBQztHQUNvQixhQUFhLENBV2xDO1NBWHFCLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBJREJfU1RPUkVfTkFNRSwgSURCX0RCX05BTUUsIExTX1BSRUZJWCwgSURCX0RCX1ZFUlNJT04sIElEQl9OT19XUkFQIH0gZnJvbSAnLi4vdG9rZW5zJztcbmltcG9ydCB7IEluZGV4ZWREQkRhdGFiYXNlIH0gZnJvbSAnLi9pbmRleGVkZGItZGF0YWJhc2UnO1xuaW1wb3J0IHsgTG9jYWxTdG9yYWdlRGF0YWJhc2UgfSBmcm9tICcuL2xvY2Fsc3RvcmFnZS1kYXRhYmFzZSc7XG5pbXBvcnQgeyBNZW1vcnlEYXRhYmFzZSB9IGZyb20gJy4vbWVtb3J5LWRhdGFiYXNlJztcblxuLyoqXG4gKiBGYWN0b3J5IHRvIGNyZWF0ZSBhIHN0b3JhZ2UgYWNjb3JkaW5nIHRvIGJyb3dzZXIgc3VwcG9ydFxuICogQHBhcmFtIHBsYXRmb3JtSWQgQ29udGV4dCBhYm91dCB0aGUgcGxhdGZvcm0gKGBicm93c2VyYCwgYHNlcnZlcmAuLi4pXG4gKiBAcGFyYW0gTFNQcmVmaXggUHJlZml4IGZvciBgbG9jYWxTdG9yYWdlYCBrZXlzIHRvIGF2b2lkIGNvbGxpc2lvbiBmb3IgbXVsdGlwbGUgYXBwcyBvbiB0aGUgc2FtZSBzdWJkb21haW5cbiAqIEBwYXJhbSBJREJEQk5hbWUgYGluZGV4ZWREQmAgZGF0YWJhc2UgbmFtZVxuICogQHBhcmFtIElEQnN0b3JlTmFtZSBgaW5kZXhlZERCYCBzdG9yZU5hbWUgbmFtZVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21hc3Rlci9kb2NzL0JST1dTRVJTX1NVUFBPUlQubWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2NhbERhdGFiYXNlRmFjdG9yeShcbiAgcGxhdGZvcm1JZDogc3RyaW5nLCBMU1ByZWZpeDogc3RyaW5nLCBJREJEQk5hbWU6IHN0cmluZywgSURCU3RvcmVOYW1lOiBzdHJpbmcsXG4gIElEQkRCVmVyc2lvbjogbnVtYmVyLCBJREJOb1dyYXA6IGJvb2xlYW4pOiBMb2NhbERhdGFiYXNlIHtcblxuICAvKiBXaGVuIHN0b3JhZ2UgaXMgZnVsbHkgZGlzYWJsZWQgaW4gYnJvd3NlciAodmlhIHRoZSBcIkJsb2NrIGFsbCBjb29raWVzXCIgb3B0aW9uKSxcbiAgICoganVzdCB0cnlpbmcgdG8gY2hlY2sgYGluZGV4ZWREQmAgb3IgYGxvY2FsU3RvcmFnZWAgdmFyaWFibGVzIGNhdXNlcyBhIHNlY3VyaXR5IGV4Y2VwdGlvbi5cbiAgICogUHJldmVudHMgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvMTE4XG4gICAqL1xuICB0cnkge1xuXG4gICAgLy8gRG8gbm90IGV4cGxpY2l0IGB3aW5kb3dgIGhlcmUsIGFzIHRoZSBnbG9iYWwgb2JqZWN0IGlzIG5vdCB0aGUgc2FtZSBpbiB3ZWIgd29ya2Vyc1xuICAgIGlmIChpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKSAmJiAoaW5kZXhlZERCICE9PSB1bmRlZmluZWQpICYmIChpbmRleGVkREIgIT09IG51bGwpICYmICgnb3BlbicgaW4gaW5kZXhlZERCKSkge1xuXG4gICAgICAvKiBDaGVjazpcbiAgICAgICogLSBpZiB3ZSBhcmUgaW4gYSBicm93c2VyIGNvbnRleHQgKGlzc3VlOiBzZXJ2ZXItc2lkZSByZW5kZXJpbmcpXG4gICAgICAqIC0gaWYgYGluZGV4ZWREQmAgZXhpc3RzIChpc3N1ZTogSUU5KVxuICAgICAgKiAtIGl0IGNvdWxkIGV4aXN0IGJ1dCBiZSBgdW5kZWZpbmVkYCBvciBgbnVsbGAgKGlzc3VlOiBJRSAvIEVkZ2UgcHJpdmF0ZSBtb2RlKVxuICAgICAgKiAtIGl0IGNvdWxkIGV4aXN0cyBidXQgbm90IGhhdmluZyBhIHdvcmtpbmcgQVBJXG4gICAgICAqIFdpbGwgYmUgdGhlIGNhc2UgZm9yOlxuICAgICAgKiAtIElFMTArIGFuZCBhbGwgb3RoZXIgYnJvd3NlcnMgaW4gbm9ybWFsIG1vZGVcbiAgICAgICogLSBDaHJvbWl1bSAvIFNhZmFyaSBwcml2YXRlIG1vZGUsIGJ1dCBpbiB0aGlzIGNhc2UsIGRhdGEgd2lsbCBiZSBzd2lwZWQgd2hlbiB0aGUgdXNlciBsZWF2ZXMgdGhlIGFwcCAqL1xuICAgICAgcmV0dXJuIG5ldyBJbmRleGVkREJEYXRhYmFzZShJREJEQk5hbWUsIElEQlN0b3JlTmFtZSwgSURCREJWZXJzaW9uLCBJREJOb1dyYXApO1xuXG4gICAgfSBlbHNlIGlmIChpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKVxuICAgICYmIChsb2NhbFN0b3JhZ2UgIT09IHVuZGVmaW5lZCkgJiYgKGxvY2FsU3RvcmFnZSAhPT0gbnVsbCkgJiYgKCdnZXRJdGVtJyBpbiBsb2NhbFN0b3JhZ2UpKSB7XG5cbiAgICAgIC8qIENoZWNrOlxuICAgICAgKiAtIGlmIHdlIGFyZSBpbiBhIGJyb3dzZXIgY29udGV4dCAoaXNzdWU6IHNlcnZlci1zaWRlIHJlbmRlcmluZylcbiAgICAgICogLSBpZiBgbG9jYWxTdG9yYWdlYCBleGlzdHMgKHRvIGJlIHN1cmUpXG4gICAgICAqIC0gaXQgY291bGQgZXhpc3RzIGJ1dCBub3QgaGF2aW5nIGEgd29ya2luZyBBUElcbiAgICAgICogV2lsbCBiZSB0aGUgY2FzZSBmb3I6XG4gICAgICAqIC0gSUU5XG4gICAgICAqIC0gU2FmYXJpIGNyb3NzLW9yaWdpbiBpZnJhbWVzLCBkZXRlY3RlZCBsYXRlciBpbiBgSW5kZXhlZERCRGF0YWJhc2UuY29ubmVjdCgpYFxuICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy80Mn1cbiAgICAgICogLSBJRSAvIEVkZ2UgLyBGaXJlZm94IHByaXZhdGUgbW9kZSwgYnV0IGluIHRoaXMgY2FzZSwgZGF0YSB3aWxsIGJlIHN3aXBlZCB3aGVuIHRoZSB1c2VyIGxlYXZlcyB0aGUgYXBwXG4gICAgICAqIEZvciBGaXJlZm94LCBjYW4gb25seSBiZSBkZXRlY3RlZCBsYXRlciBpbiBgSW5kZXhlZERCRGF0YWJhc2UuY29ubmVjdCgpYFxuICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD03ODE5ODJ9XG4gICAgICAqL1xuICAgICAgcmV0dXJuIG5ldyBMb2NhbFN0b3JhZ2VEYXRhYmFzZShMU1ByZWZpeCk7XG5cbiAgICB9XG5cbiAgfSBjYXRjaCB7fVxuXG4gIC8qIFdpbGwgYmUgdGhlIGNhc2UgZm9yOlxuICAgKiAtIEluIGJyb3dzZXJzIGlmIHN0b3JhZ2UgaGFzIGJlZW4gZnVsbHkgZGlzYWJsZWQgKHZpYSB0aGUgXCJCbG9jayBhbGwgY29va2llc1wiIG9wdGlvbilcbiAgICogLSBTZXJ2ZXItc2lkZSByZW5kZXJpbmdcbiAgICogLSBBbGwgb3RoZXIgbm9uLWJyb3dzZXIgY29udGV4dFxuICAgKi9cbiAgcmV0dXJuIG5ldyBNZW1vcnlEYXRhYmFzZSgpO1xuXG59XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICB1c2VGYWN0b3J5OiBsb2NhbERhdGFiYXNlRmFjdG9yeSxcbiAgZGVwczogW1xuICAgIFBMQVRGT1JNX0lELFxuICAgIExTX1BSRUZJWCxcbiAgICBJREJfREJfTkFNRSxcbiAgICBJREJfU1RPUkVfTkFNRSxcbiAgICBJREJfREJfVkVSU0lPTixcbiAgICBJREJfTk9fV1JBUCxcbiAgXVxufSlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMb2NhbERhdGFiYXNlIHtcblxuICBhYnN0cmFjdCByZWFkb25seSBzaXplOiBPYnNlcnZhYmxlPG51bWJlcj47XG5cbiAgYWJzdHJhY3QgZ2V0PFQgPSB1bmtub3duPihrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIGFic3RyYWN0IHNldChrZXk6IHN0cmluZywgZGF0YTogdW5rbm93bik6IE9ic2VydmFibGU8dW5kZWZpbmVkPjtcbiAgYWJzdHJhY3QgZGVsZXRlKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+O1xuICBhYnN0cmFjdCBjbGVhcigpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD47XG4gIGFic3RyYWN0IGtleXMoKTogT2JzZXJ2YWJsZTxzdHJpbmc+O1xuICBhYnN0cmFjdCBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuXG59XG4iXX0=
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtZGF0YWJhc2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LXB3YS9sb2NhbC1zdG9yYWdlLyIsInNvdXJjZXMiOlsibGliL2RhdGFiYXNlcy9sb2NhbC1kYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDeEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDaEcsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7QUFFbkQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FDbEMsVUFBa0IsRUFBRSxRQUFnQixFQUFFLFNBQWlCLEVBQUUsWUFBb0IsRUFDN0UsWUFBb0IsRUFBRSxTQUFrQjtJQUV4Qzs7O09BR0c7SUFDSCxJQUFJO1FBRUYscUZBQXFGO1FBQ3JGLElBQUksaUJBQWlCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksU0FBUyxDQUFDLEVBQUU7WUFFL0c7Ozs7Ozs7cUhBT3lHO1lBQ3pHLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUVoRjthQUFNLElBQUksaUJBQWlCLENBQUMsVUFBVSxDQUFDO2VBQ3JDLENBQUMsWUFBWSxLQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLFlBQVksQ0FBQyxFQUFFO1lBRXpGOzs7Ozs7Ozs7OztjQVdFO1lBQ0YsT0FBTyxJQUFJLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBRTNDO0tBRUY7SUFBQyxXQUFNLEdBQUU7SUFFVjs7OztPQUlHO0lBQ0gsT0FBTyxJQUFJLGNBQWMsRUFBRSxDQUFDO0FBRTlCLENBQUM7QUFjRDtJQUFBLElBQXNCLGFBQWEsR0FBbkMsTUFBc0IsYUFBYTtLQVdsQyxDQUFBOztJQVhxQixhQUFhO1FBWmxDLFVBQVUsQ0FBQztZQUNWLFVBQVUsRUFBRSxNQUFNO1lBQ2xCLFVBQVUsRUFBRSxvQkFBb0I7WUFDaEMsSUFBSSxFQUFFO2dCQUNKLFdBQVc7Z0JBQ1gsU0FBUztnQkFDVCxXQUFXO2dCQUNYLGNBQWM7Z0JBQ2QsY0FBYztnQkFDZCxXQUFXO2FBQ1o7U0FDRixDQUFDO09BQ29CLGFBQWEsQ0FXbEM7d0JBN0ZEO0tBNkZDO1NBWHFCLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBJREJfU1RPUkVfTkFNRSwgSURCX0RCX05BTUUsIExTX1BSRUZJWCwgSURCX0RCX1ZFUlNJT04sIElEQl9OT19XUkFQIH0gZnJvbSAnLi4vdG9rZW5zJztcbmltcG9ydCB7IEluZGV4ZWREQkRhdGFiYXNlIH0gZnJvbSAnLi9pbmRleGVkZGItZGF0YWJhc2UnO1xuaW1wb3J0IHsgTG9jYWxTdG9yYWdlRGF0YWJhc2UgfSBmcm9tICcuL2xvY2Fsc3RvcmFnZS1kYXRhYmFzZSc7XG5pbXBvcnQgeyBNZW1vcnlEYXRhYmFzZSB9IGZyb20gJy4vbWVtb3J5LWRhdGFiYXNlJztcblxuLyoqXG4gKiBGYWN0b3J5IHRvIGNyZWF0ZSBhIHN0b3JhZ2UgYWNjb3JkaW5nIHRvIGJyb3dzZXIgc3VwcG9ydFxuICogQHBhcmFtIHBsYXRmb3JtSWQgQ29udGV4dCBhYm91dCB0aGUgcGxhdGZvcm0gKGBicm93c2VyYCwgYHNlcnZlcmAuLi4pXG4gKiBAcGFyYW0gTFNQcmVmaXggUHJlZml4IGZvciBgbG9jYWxTdG9yYWdlYCBrZXlzIHRvIGF2b2lkIGNvbGxpc2lvbiBmb3IgbXVsdGlwbGUgYXBwcyBvbiB0aGUgc2FtZSBzdWJkb21haW5cbiAqIEBwYXJhbSBJREJEQk5hbWUgYGluZGV4ZWREQmAgZGF0YWJhc2UgbmFtZVxuICogQHBhcmFtIElEQnN0b3JlTmFtZSBgaW5kZXhlZERCYCBzdG9yZU5hbWUgbmFtZVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21hc3Rlci9kb2NzL0JST1dTRVJTX1NVUFBPUlQubWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2NhbERhdGFiYXNlRmFjdG9yeShcbiAgcGxhdGZvcm1JZDogc3RyaW5nLCBMU1ByZWZpeDogc3RyaW5nLCBJREJEQk5hbWU6IHN0cmluZywgSURCU3RvcmVOYW1lOiBzdHJpbmcsXG4gIElEQkRCVmVyc2lvbjogbnVtYmVyLCBJREJOb1dyYXA6IGJvb2xlYW4pOiBMb2NhbERhdGFiYXNlIHtcblxuICAvKiBXaGVuIHN0b3JhZ2UgaXMgZnVsbHkgZGlzYWJsZWQgaW4gYnJvd3NlciAodmlhIHRoZSBcIkJsb2NrIGFsbCBjb29raWVzXCIgb3B0aW9uKSxcbiAgICoganVzdCB0cnlpbmcgdG8gY2hlY2sgYGluZGV4ZWREQmAgb3IgYGxvY2FsU3RvcmFnZWAgdmFyaWFibGVzIGNhdXNlcyBhIHNlY3VyaXR5IGV4Y2VwdGlvbi5cbiAgICogUHJldmVudHMgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvMTE4XG4gICAqL1xuICB0cnkge1xuXG4gICAgLy8gRG8gbm90IGV4cGxpY2l0IGB3aW5kb3dgIGhlcmUsIGFzIHRoZSBnbG9iYWwgb2JqZWN0IGlzIG5vdCB0aGUgc2FtZSBpbiB3ZWIgd29ya2Vyc1xuICAgIGlmIChpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKSAmJiAoaW5kZXhlZERCICE9PSB1bmRlZmluZWQpICYmIChpbmRleGVkREIgIT09IG51bGwpICYmICgnb3BlbicgaW4gaW5kZXhlZERCKSkge1xuXG4gICAgICAvKiBDaGVjazpcbiAgICAgICogLSBpZiB3ZSBhcmUgaW4gYSBicm93c2VyIGNvbnRleHQgKGlzc3VlOiBzZXJ2ZXItc2lkZSByZW5kZXJpbmcpXG4gICAgICAqIC0gaWYgYGluZGV4ZWREQmAgZXhpc3RzIChpc3N1ZTogSUU5KVxuICAgICAgKiAtIGl0IGNvdWxkIGV4aXN0IGJ1dCBiZSBgdW5kZWZpbmVkYCBvciBgbnVsbGAgKGlzc3VlOiBJRSAvIEVkZ2UgcHJpdmF0ZSBtb2RlKVxuICAgICAgKiAtIGl0IGNvdWxkIGV4aXN0cyBidXQgbm90IGhhdmluZyBhIHdvcmtpbmcgQVBJXG4gICAgICAqIFdpbGwgYmUgdGhlIGNhc2UgZm9yOlxuICAgICAgKiAtIElFMTArIGFuZCBhbGwgb3RoZXIgYnJvd3NlcnMgaW4gbm9ybWFsIG1vZGVcbiAgICAgICogLSBDaHJvbWl1bSAvIFNhZmFyaSBwcml2YXRlIG1vZGUsIGJ1dCBpbiB0aGlzIGNhc2UsIGRhdGEgd2lsbCBiZSBzd2lwZWQgd2hlbiB0aGUgdXNlciBsZWF2ZXMgdGhlIGFwcCAqL1xuICAgICAgcmV0dXJuIG5ldyBJbmRleGVkREJEYXRhYmFzZShJREJEQk5hbWUsIElEQlN0b3JlTmFtZSwgSURCREJWZXJzaW9uLCBJREJOb1dyYXApO1xuXG4gICAgfSBlbHNlIGlmIChpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKVxuICAgICYmIChsb2NhbFN0b3JhZ2UgIT09IHVuZGVmaW5lZCkgJiYgKGxvY2FsU3RvcmFnZSAhPT0gbnVsbCkgJiYgKCdnZXRJdGVtJyBpbiBsb2NhbFN0b3JhZ2UpKSB7XG5cbiAgICAgIC8qIENoZWNrOlxuICAgICAgKiAtIGlmIHdlIGFyZSBpbiBhIGJyb3dzZXIgY29udGV4dCAoaXNzdWU6IHNlcnZlci1zaWRlIHJlbmRlcmluZylcbiAgICAgICogLSBpZiBgbG9jYWxTdG9yYWdlYCBleGlzdHMgKHRvIGJlIHN1cmUpXG4gICAgICAqIC0gaXQgY291bGQgZXhpc3RzIGJ1dCBub3QgaGF2aW5nIGEgd29ya2luZyBBUElcbiAgICAgICogV2lsbCBiZSB0aGUgY2FzZSBmb3I6XG4gICAgICAqIC0gSUU5XG4gICAgICAqIC0gU2FmYXJpIGNyb3NzLW9yaWdpbiBpZnJhbWVzLCBkZXRlY3RlZCBsYXRlciBpbiBgSW5kZXhlZERCRGF0YWJhc2UuY29ubmVjdCgpYFxuICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2lzc3Vlcy80Mn1cbiAgICAgICogLSBJRSAvIEVkZ2UgLyBGaXJlZm94IHByaXZhdGUgbW9kZSwgYnV0IGluIHRoaXMgY2FzZSwgZGF0YSB3aWxsIGJlIHN3aXBlZCB3aGVuIHRoZSB1c2VyIGxlYXZlcyB0aGUgYXBwXG4gICAgICAqIEZvciBGaXJlZm94LCBjYW4gb25seSBiZSBkZXRlY3RlZCBsYXRlciBpbiBgSW5kZXhlZERCRGF0YWJhc2UuY29ubmVjdCgpYFxuICAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD03ODE5ODJ9XG4gICAgICAqL1xuICAgICAgcmV0dXJuIG5ldyBMb2NhbFN0b3JhZ2VEYXRhYmFzZShMU1ByZWZpeCk7XG5cbiAgICB9XG5cbiAgfSBjYXRjaCB7fVxuXG4gIC8qIFdpbGwgYmUgdGhlIGNhc2UgZm9yOlxuICAgKiAtIEluIGJyb3dzZXJzIGlmIHN0b3JhZ2UgaGFzIGJlZW4gZnVsbHkgZGlzYWJsZWQgKHZpYSB0aGUgXCJCbG9jayBhbGwgY29va2llc1wiIG9wdGlvbilcbiAgICogLSBTZXJ2ZXItc2lkZSByZW5kZXJpbmdcbiAgICogLSBBbGwgb3RoZXIgbm9uLWJyb3dzZXIgY29udGV4dFxuICAgKi9cbiAgcmV0dXJuIG5ldyBNZW1vcnlEYXRhYmFzZSgpO1xuXG59XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICB1c2VGYWN0b3J5OiBsb2NhbERhdGFiYXNlRmFjdG9yeSxcbiAgZGVwczogW1xuICAgIFBMQVRGT1JNX0lELFxuICAgIExTX1BSRUZJWCxcbiAgICBJREJfREJfTkFNRSxcbiAgICBJREJfU1RPUkVfTkFNRSxcbiAgICBJREJfREJfVkVSU0lPTixcbiAgICBJREJfTk9fV1JBUCxcbiAgXVxufSlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMb2NhbERhdGFiYXNlIHtcblxuICBhYnN0cmFjdCByZWFkb25seSBzaXplOiBPYnNlcnZhYmxlPG51bWJlcj47XG5cbiAgYWJzdHJhY3QgZ2V0PFQgPSB1bmtub3duPihrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIGFic3RyYWN0IHNldChrZXk6IHN0cmluZywgZGF0YTogdW5rbm93bik6IE9ic2VydmFibGU8dW5kZWZpbmVkPjtcbiAgYWJzdHJhY3QgZGVsZXRlKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+O1xuICBhYnN0cmFjdCBjbGVhcigpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD47XG4gIGFic3RyYWN0IGtleXMoKTogT2JzZXJ2YWJsZTxzdHJpbmc+O1xuICBhYnN0cmFjdCBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuXG59XG4iXX0=

@@ -9,32 +9,58 @@ import { __decorate, __param } from "tslib";

import * as i1 from "../tokens";
let LocalStorageDatabase = class LocalStorageDatabase {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param prefix Prefix option to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(prefix = '') {
/* Prefix if asked, or no prefix otherwise */
this.prefix = prefix || '';
}
/**
* Number of items in `localStorage`
*/
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(localStorage.length);
}
/**
* Gets an item value in `localStorage`
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
/* Get raw data */
const unparsedData = localStorage.getItem(this.prefixKey(key));
let parsedData;
/* No need to parse if data is `null` or `undefined` */
if ((unparsedData !== undefined) && (unparsedData !== null)) {
/* Try to parse */
let LocalStorageDatabase = /** @class */ (() => {
let LocalStorageDatabase = class LocalStorageDatabase {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param prefix Prefix option to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(prefix = '') {
/* Prefix if asked, or no prefix otherwise */
this.prefix = prefix || '';
}
/**
* Number of items in `localStorage`
*/
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(localStorage.length);
}
/**
* Gets an item value in `localStorage`
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
/* Get raw data */
const unparsedData = localStorage.getItem(this.prefixKey(key));
let parsedData;
/* No need to parse if data is `null` or `undefined` */
if ((unparsedData !== undefined) && (unparsedData !== null)) {
/* Try to parse */
try {
parsedData = JSON.parse(unparsedData);
}
catch (error) {
return throwError(error);
}
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(parsedData);
}
/**
* Store an item in `localStorage`
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
let serializedData = null;
/* Check if data can be serialized */
const dataPrototype = Object.getPrototypeOf(data);
if ((typeof data === 'object') && (data !== null) && !Array.isArray(data) &&
!((dataPrototype === Object.prototype) || (dataPrototype === null))) {
return throwError(new SerializationError());
}
/* Try to stringify (can fail on circular references) */
try {
parsedData = JSON.parse(unparsedData);
serializedData = JSON.stringify(data);
}

@@ -44,124 +70,101 @@ catch (error) {

}
/* Can fail if storage quota is exceeded */
try {
localStorage.setItem(this.prefixKey(key), serializedData);
}
catch (error) {
return throwError(error);
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(parsedData);
}
/**
* Store an item in `localStorage`
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
let serializedData = null;
/* Check if data can be serialized */
const dataPrototype = Object.getPrototypeOf(data);
if ((typeof data === 'object') && (data !== null) && !Array.isArray(data) &&
!((dataPrototype === Object.prototype) || (dataPrototype === null))) {
return throwError(new SerializationError());
/**
* Deletes an item in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
localStorage.removeItem(this.prefixKey(key));
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/* Try to stringify (can fail on circular references) */
try {
serializedData = JSON.stringify(data);
/**
* Deletes all items in `localStorage`
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
localStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
catch (error) {
return throwError(error);
/**
* Get all keys in `localStorage`
* Note the order of the keys may be inconsistent in Firefox
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return new Observable((subscriber) => {
/* Iteretate over all the indexes */
for (let index = 0; index < localStorage.length; index += 1) {
/* Cast as we are sure in this case the key is not `null` */
subscriber.next(this.getUnprefixedKey(index));
}
subscriber.complete();
}).pipe(
/* Required to work like other databases which are asynchronous */
observeOn(asyncScheduler));
}
/* Can fail if storage quota is exceeded */
try {
localStorage.setItem(this.prefixKey(key), serializedData);
}
catch (error) {
return throwError(error);
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes an item in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
localStorage.removeItem(this.prefixKey(key));
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes all items in `localStorage`
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
localStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Get all keys in `localStorage`
* Note the order of the keys may be inconsistent in Firefox
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return new Observable((subscriber) => {
/* Iteretate over all the indexes */
/**
* Check if a key exists in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Itérate over all indexes in storage */
for (let index = 0; index < localStorage.length; index += 1) {
/* Cast as we are sure in this case the key is not `null` */
subscriber.next(this.getUnprefixedKey(index));
if (key === this.getUnprefixedKey(index)) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(true);
}
}
subscriber.complete();
}).pipe(
/* Required to work like other databases which are asynchronous */
observeOn(asyncScheduler));
}
/**
* Check if a key exists in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Itérate over all indexes in storage */
for (let index = 0; index < localStorage.length; index += 1) {
if (key === this.getUnprefixedKey(index)) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(true);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(false);
}
/**
* Get an unprefixed key
* @param index Index of the key
* @returns The unprefixed key name if exists, `null` otherwise
*/
getUnprefixedKey(index) {
/* Get the key in storage: may have a prefix */
const prefixedKey = localStorage.key(index);
if (prefixedKey !== null) {
/* If no prefix, the key is already good, otherwrite strip the prefix */
return !this.prefix ? prefixedKey : prefixedKey.substr(this.prefix.length);
}
return null;
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(false);
}
/**
* Get an unprefixed key
* @param index Index of the key
* @returns The unprefixed key name if exists, `null` otherwise
*/
getUnprefixedKey(index) {
/* Get the key in storage: may have a prefix */
const prefixedKey = localStorage.key(index);
if (prefixedKey !== null) {
/* If no prefix, the key is already good, otherwrite strip the prefix */
return !this.prefix ? prefixedKey : prefixedKey.substr(this.prefix.length);
/**
* Add the prefix to a key
* @param key The key name
* @returns The prefixed key name
*/
prefixKey(key) {
return `${this.prefix}${key}`;
}
return null;
}
/**
* Add the prefix to a key
* @param key The key name
* @returns The prefixed key name
*/
prefixKey(key) {
return `${this.prefix}${key}`;
}
};
LocalStorageDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
LocalStorageDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalStorageDatabase_Factory() { return new LocalStorageDatabase(i0.ɵɵinject(i1.LS_PREFIX)); }, token: LocalStorageDatabase, providedIn: "root" });
LocalStorageDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(LS_PREFIX))
], LocalStorageDatabase);
};
LocalStorageDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
LocalStorageDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalStorageDatabase_Factory() { return new LocalStorageDatabase(i0.ɵɵinject(i1.LS_PREFIX)); }, token: LocalStorageDatabase, providedIn: "root" });
LocalStorageDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(LS_PREFIX))
], LocalStorageDatabase);
return LocalStorageDatabase;
})();
export { LocalStorageDatabase };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWxzdG9yYWdlLWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9kYXRhYmFzZXMvbG9jYWxzdG9yYWdlLWRhdGFiYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXRDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7O0FBS2xELElBQWEsb0JBQW9CLEdBQWpDLE1BQWEsb0JBQW9CO0lBTy9COzs7T0FHRztJQUNILFlBQ3FCLFNBQVMsRUFBRTtRQUc5Qiw2Q0FBNkM7UUFDN0MsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO0lBRTdCLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksSUFBSTtRQUVOLHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFakMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxHQUFHLENBQWMsR0FBVztRQUUxQixrQkFBa0I7UUFDbEIsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFL0QsSUFBSSxVQUF5QixDQUFDO1FBRTlCLHVEQUF1RDtRQUN2RCxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxFQUFFO1lBRTNELGtCQUFrQjtZ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RUFBRTtnQkFFeEMsc0VBQXNFO2dCQUN0RSxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUVqQjtTQUVGO1FBRUQsc0VBQXNFO1FBQ3RFLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRW5CLENBQUM7SUFFRDs7OztPQUlHO0lBQ08sZ0JBQWdCLENBQUMsS0FBYTtRQUV0QywrQ0FBK0M7UUFDL0MsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUU1QyxJQUFJLFdBQVcsS0FBSyxJQUFJLEVBQUU7WUFFeEIsd0VBQXdFO1lBQ3hFLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUU1RTtRQUVELE9BQU8sSUFBSSxDQUFDO0lBRWQsQ0FBQztJQUVEOzs7O09BSUc7SUFDTyxTQUFTLENBQUMsR0FBVztRQUU3QixPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUVoQyxDQUFDO0NBRUYsQ0FBQTs7NENBak1JLE1BQU0sU0FBQyxTQUFTOzs7QUFaUixvQkFBb0I7SUFIaEMsVUFBVSxDQUFDO1FBQ1YsVUFBVSxFQUFFLE1BQU07S0FDbkIsQ0FBQztJQWFHLFdBQUEsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0dBWlQsb0JBQW9CLENBNk1oQztTQTdNWSxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yLCBhc3luY1NjaGVkdWxlciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgb2JzZXJ2ZU9uIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBMU19QUkVGSVggfSBmcm9tICcuLi90b2tlbnMnO1xuaW1wb3J0IHsgTG9jYWxEYXRhYmFzZSB9IGZyb20gJy4vbG9jYWwtZGF0YWJhc2UnO1xuaW1wb3J0IHsgU2VyaWFsaXphdGlvbkVycm9yIH0gZnJvbSAnLi9leGNlcHRpb25zJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTG9jYWxTdG9yYWdlRGF0YWJhc2UgaW1wbGVtZW50cyBMb2NhbERhdGFiYXNlIHtcblxuICAvKipcbiAgICogT3B0aW9uYWwgdXNlciBwcmVmaXggdG8gYXZvaWQgY29sbGlzaW9uIGZvciBtdWx0aXBsZSBhcHBzIG9uIHRoZSBzYW1lIHN1YmRvbWFpblxuICAgKi9cbiAgcmVhZG9ubHkgcHJlZml4OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIHBhcmFtcyBhcmUgcHJvdmlkZWQgYnkgQW5ndWxhciAoYnV0IGNhbiBhbHNvIGJlIHBhc3NlZCBtYW51YWxseSBpbiB0ZXN0cylcbiAgICogQHBhcmFtIHByZWZpeCBQcmVmaXggb3B0aW9uIHRvIGF2b2lkIGNvbGxpc2lvbiBmb3IgbXVsdGlwbGUgYXBwcyBvbiB0aGUgc2FtZSBzdWJkb21haW4gb3IgZm9yIGludGVyb3BlcmFiaWxpdHlcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoTFNfUFJFRklYKSBwcmVmaXggPSAnJyxcbiAgKSB7XG5cbiAgICAvKiBQcmVmaXggaWYgYXNrZWQsIG9yIG5vIHByZWZpeCBvdGhlcndpc2UgKi9cbiAgICB0aGlzLnByZWZpeCA9IHByZWZpeCB8fCAnJztcblxuICB9XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBpdGVtcyBpbiBgbG9jYWxTdG9yYWdlYFxuICAgKi9cbiAgZ2V0IHNpemUoKTogT2JzZXJ2YWJsZTxudW1iZXI+IHtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YobG9jYWxTdG9yYWdlLmxlbmd0aCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFuIGl0ZW0gdmFsdWUgaW4gYGxvY2FsU3RvcmFnZWBcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcmV0dXJucyBUaGUgaXRlbSdzIHZhbHVlIGlmIHRoZSBrZXkgZXhpc3RzLCBgdW5kZWZpbmVkYCBvdGhlcndpc2UsIHdyYXBwZWQgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYFxuICAgKi9cbiAgZ2V0PFQgPSB1bmtub3duPihrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD4ge1xuXG4gICAgLyogR2V0IHJhdyBkYXRhICovXG4gICAgY29uc3QgdW5wYXJzZWREYXRhID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5wcmVmaXhLZXkoa2V5KSk7XG5cbiAgICBsZXQgcGFyc2VkRGF0YTogVCB8IHVuZGVmaW5lZDtcblxuICAgIC8qIE5vIG5lZWQgdG8gcGFyc2UgaWYgZGF0YSBpcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgKi9cbiAgICBpZiAoKHVucGFyc2VkRGF0YSAhPT0gdW5kZWZpbmVkKSAmJiAodW5wYXJzZWREYXRhICE9PSBudWxsKSkge1xuXG4gICAgICAvKiBUcnkgdG8gcGFyc2UgKi9cbiAgICAgIHRyeSB7XG4gICAgICAgIHBhcnNlZERhdGEgPSBKU09OLnBhcnNlKHVucGFyc2VkRGF0YSkgYXMgVDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yIGFzIFN5bnRheEVycm9yKTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YocGFyc2VkRGF0YSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9yZSBhbiBpdGVtIGluIGBsb2NhbFN0b3JhZ2VgXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHBhcmFtIGRhdGEgVGhlIGl0ZW0ncyB2YWx1ZVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqL1xuICBzZXQoa2V5OiBzdHJpbmcsIGRhdGE6IHVua25vd24pOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgbGV0IHNlcmlhbGl6ZWREYXRhOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgIC8qIENoZWNrIGlmIGRhdGEgY2FuIGJlIHNlcmlhbGl6ZWQgKi9cbiAgICBjb25zdCBkYXRhUHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpO1xuICAgIGlmICgodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSAmJiAoZGF0YSAhPT0gbnVsbCkgJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkgJiZcbiAgICAhKChkYXRhUHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlKSB8fCAoZGF0YVByb3RvdHlwZSA9PT0gbnVsbCkpKSB7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcihuZXcgU2VyaWFsaXphdGlvbkVycm9yKCkpO1xuICAgIH1cblxuICAgIC8qIFRyeSB0byBzdHJpbmdpZnkgKGNhbiBmYWlsIG9uIGNpcmN1bGFyIHJlZmVyZW5jZXMpICovXG4gICAgdHJ5IHtcbiAgICAgIHNlcmlhbGl6ZWREYXRhID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yIGFzIFR5cGVFcnJvcik7XG4gICAgfVxuXG4gICAgLyogQ2FuIGZhaWwgaWYgc3RvcmFnZSBxdW90YSBpcyBleGNlZWRlZCAqL1xuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLnByZWZpeEtleShrZXkpLCBzZXJpYWxpemVkRGF0YSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yIGFzIERPTUV4Y2VwdGlvbik7XG4gICAgfVxuXG4gICAgLyogV3JhcCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzdG9yYWdlcyAqL1xuICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBhbiBpdGVtIGluIGBsb2NhbFN0b3JhZ2VgXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMucHJlZml4S2V5KGtleSkpO1xuXG4gICAgLyogV3JhcCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzdG9yYWdlcyAqL1xuICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBhbGwgaXRlbXMgaW4gYGxvY2FsU3RvcmFnZWBcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgY2xlYXIoKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIGxvY2FsU3RvcmFnZS5jbGVhcigpO1xuXG4gICAgLyogV3JhcCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzdG9yYWdlcyAqL1xuICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuXG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBrZXlzIGluIGBsb2NhbFN0b3JhZ2VgXG4gICAqIE5vdGUgdGhlIG9yZGVyIG9mIHRoZSBrZXlzIG1heSBiZSBpbmNvbnNpc3RlbnQgaW4gRmlyZWZveFxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIGl0ZXJhdGluZyBvbiBrZXlzXG4gICAqL1xuICBrZXlzKCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG5cbiAgICAvKiBDcmVhdGUgYW4gYE9ic2VydmFibGVgIGZyb20ga2V5cyAqL1xuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxzdHJpbmc+KChzdWJzY3JpYmVyKSA9PiB7XG5cbiAgICAgIC8qIEl0ZXJldGF0ZSBvdmVyIGFsbCB0aGUgaW5kZXhlcyAqL1xuICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxvY2FsU3RvcmFnZS5sZW5ndGg7IGluZGV4ICs9IDEpIHtcblxuICAgICAgICAvKiBDYXN0IGFzIHdlIGFyZSBzdXJlIGluIHRoaXMgY2FzZSB0aGUga2V5IGlzIG5vdCBgbnVsbGAgKi9cbiAgICAgICAgc3Vic2NyaWJlci5uZXh0KHRoaXMuZ2V0VW5wcmVmaXhlZEtleShpbmRleCkgYXMgc3RyaW5nKTtcblxuICAgICAgfVxuXG4gICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG5cbiAgICB9KS5waXBlKFxuICAgICAgLyogUmVxdWlyZWQgdG8gd29yayBsaWtlIG90aGVyIGRhdGFiYXNlcyB3aGljaCBhcmUgYXN5bmNocm9ub3VzICovXG4gICAgICBvYnNlcnZlT24oYXN5bmNTY2hlZHVsZXIpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGtleSBleGlzdHMgaW4gYGxvY2FsU3RvcmFnZWBcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRlbGxpbmcgaWYgdGhlIGtleSBleGlzdHMgb3Igbm90XG4gICAqL1xuICBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIC8qIEl0w6lyYXRlIG92ZXIgYWxsIGluZGV4ZXMgaW4gc3RvcmFnZSAqL1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsb2NhbFN0b3JhZ2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG5cbiAgICAgIGlmIChrZXkgPT09IHRoaXMuZ2V0VW5wcmVmaXhlZEtleShpbmRleCkpwqB7XG5cbiAgICAgICAgLyogV3JhcCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzdG9yYWdlcyAqL1xuICAgICAgICByZXR1cm4gb2YodHJ1ZSk7XG5cbiAgICAgIH1cblxuICAgIH1cblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YoZmFsc2UpO1xuXG4gIH1cblxuICAvKipcbiAgICogR2V0IGFuIHVucHJlZml4ZWQga2V5XG4gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB0aGUga2V5XG4gICAqIEByZXR1cm5zIFRoZSB1bnByZWZpeGVkIGtleSBuYW1lIGlmIGV4aXN0cywgYG51bGxgIG90aGVyd2lzZVxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucHJlZml4ZWRLZXkoaW5kZXg6IG51bWJlcik6IHN0cmluZyB8IG51bGwge1xuXG4gICAgLyogR2V0IHRoZSBrZXkgaW4gc3RvcmFnZTogbWF5IGhhdmUgYSBwcmVmaXggKi9cbiAgICBjb25zdCBwcmVmaXhlZEtleSA9IGxvY2FsU3RvcmFnZS5rZXkoaW5kZXgpO1xuXG4gICAgaWYgKHByZWZpeGVkS2V5ICE9PSBudWxsKSB7XG5cbiAgICAgIC8qIElmIG5vIHByZWZpeCwgdGhlIGtleSBpcyBhbHJlYWR5IGdvb2QsIG90aGVyd3JpdGUgc3RyaXAgdGhlIHByZWZpeCAqL1xuICAgICAgcmV0dXJuICF0aGlzLnByZWZpeCA/IHByZWZpeGVkS2V5IDogcHJlZml4ZWRLZXkuc3Vic3RyKHRoaXMucHJlZml4Lmxlbmd0aCk7XG5cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcblxuICB9XG5cbiAgLyoqXG4gICAqIEFkZCB0aGUgcHJlZml4IHRvIGEga2V5XG4gICAqIEBwYXJhbSBrZXkgVGhlIGtleSBuYW1lXG4gICAqIEByZXR1cm5zIFRoZSBwcmVmaXhlZCBrZXkgbmFtZVxuICAgKi9cbiAgcHJvdGVjdGVkIHByZWZpeEtleShrZXk6IHN0cmluZyk6IHN0cmluZyB7XG5cbiAgICByZXR1cm4gYCR7dGhpcy5wcmVmaXh9JHtrZXl9YDtcblxuICB9XG5cbn1cbiJdfQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWxzdG9yYWdlLWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9kYXRhYmFzZXMvbG9jYWxzdG9yYWdlLWRhdGFiYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXRDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7O0FBS2xEO0lBQUEsSUFBYSxvQkFBb0IsR0FBakMsTUFBYSxvQkFBb0I7UUFPL0I7OztXQUdHO1FBQ0gsWUFDcUIsU0FBUyxFQUFFO1lBRzlCLDZDQUE2QztZQUM3QyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFFN0IsQ0FBQztRQUVEOztXQUVHO1FBQ0gsSUFBSSxJQUFJO1lBRU4sc0VBQXNFO1lBQ3RFLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVqQyxDQUFDO1FBRUQ7Ozs7V0FJRztRQUNILEdBQUcsQ0FBYyxHQUFXO1lBRTFCLGtCQUFrQjtZQUNsQixNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUUvRCxJQUFJLFVBQXlCLENBQUM7WUFFOUIsdURBQXVEO1lBQ3ZELElBQUksQ0FBQyxZQUFZLEtBQUssU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDLEVBQUU7Z0JBRTNELGtC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QkFBZ0IsQ0FBQyxLQUFLLENBQUMsRUFBRTtvQkFFeEMsc0VBQXNFO29CQUN0RSxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztpQkFFakI7YUFFRjtZQUVELHNFQUFzRTtZQUN0RSxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVuQixDQUFDO1FBRUQ7Ozs7V0FJRztRQUNPLGdCQUFnQixDQUFDLEtBQWE7WUFFdEMsK0NBQStDO1lBQy9DLE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFNUMsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFO2dCQUV4Qix3RUFBd0U7Z0JBQ3hFLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUU1RTtZQUVELE9BQU8sSUFBSSxDQUFDO1FBRWQsQ0FBQztRQUVEOzs7O1dBSUc7UUFDTyxTQUFTLENBQUMsR0FBVztZQUU3QixPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUVoQyxDQUFDO0tBRUYsQ0FBQTs7Z0RBak1JLE1BQU0sU0FBQyxTQUFTOzs7SUFaUixvQkFBb0I7UUFIaEMsVUFBVSxDQUFDO1lBQ1YsVUFBVSxFQUFFLE1BQU07U0FDbkIsQ0FBQztRQWFHLFdBQUEsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFBO09BWlQsb0JBQW9CLENBNk1oQzsrQkF4TkQ7S0F3TkM7U0E3TVksb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiwgdGhyb3dFcnJvciwgYXN5bmNTY2hlZHVsZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG9ic2VydmVPbiB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTFNfUFJFRklYIH0gZnJvbSAnLi4vdG9rZW5zJztcbmltcG9ydCB7IExvY2FsRGF0YWJhc2UgfSBmcm9tICcuL2xvY2FsLWRhdGFiYXNlJztcbmltcG9ydCB7IFNlcmlhbGl6YXRpb25FcnJvciB9IGZyb20gJy4vZXhjZXB0aW9ucyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIExvY2FsU3RvcmFnZURhdGFiYXNlIGltcGxlbWVudHMgTG9jYWxEYXRhYmFzZSB7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIHVzZXIgcHJlZml4IHRvIGF2b2lkIGNvbGxpc2lvbiBmb3IgbXVsdGlwbGUgYXBwcyBvbiB0aGUgc2FtZSBzdWJkb21haW5cbiAgICovXG4gIHJlYWRvbmx5IHByZWZpeDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvciBwYXJhbXMgYXJlIHByb3ZpZGVkIGJ5IEFuZ3VsYXIgKGJ1dCBjYW4gYWxzbyBiZSBwYXNzZWQgbWFudWFsbHkgaW4gdGVzdHMpXG4gICAqIEBwYXJhbSBwcmVmaXggUHJlZml4IG9wdGlvbiB0byBhdm9pZCBjb2xsaXNpb24gZm9yIG11bHRpcGxlIGFwcHMgb24gdGhlIHNhbWUgc3ViZG9tYWluIG9yIGZvciBpbnRlcm9wZXJhYmlsaXR5XG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KExTX1BSRUZJWCkgcHJlZml4ID0gJycsXG4gICkge1xuXG4gICAgLyogUHJlZml4IGlmIGFza2VkLCBvciBubyBwcmVmaXggb3RoZXJ3aXNlICovXG4gICAgdGhpcy5wcmVmaXggPSBwcmVmaXggfHwgJyc7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaXRlbXMgaW4gYGxvY2FsU3RvcmFnZWBcbiAgICovXG4gIGdldCBzaXplKCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKGxvY2FsU3RvcmFnZS5sZW5ndGgpO1xuXG4gIH1cblxuICAvKipcbiAgICogR2V0cyBhbiBpdGVtIHZhbHVlIGluIGBsb2NhbFN0b3JhZ2VgXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgVGhlIGl0ZW0ncyB2YWx1ZSBpZiB0aGUga2V5IGV4aXN0cywgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLCB3cmFwcGVkIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICovXG4gIGdldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+IHtcblxuICAgIC8qIEdldCByYXcgZGF0YSAqL1xuICAgIGNvbnN0IHVucGFyc2VkRGF0YSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMucHJlZml4S2V5KGtleSkpO1xuXG4gICAgbGV0IHBhcnNlZERhdGE6IFQgfCB1bmRlZmluZWQ7XG5cbiAgICAvKiBObyBuZWVkIHRvIHBhcnNlIGlmIGRhdGEgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgICovXG4gICAgaWYgKCh1bnBhcnNlZERhdGEgIT09IHVuZGVmaW5lZCkgJiYgKHVucGFyc2VkRGF0YSAhPT0gbnVsbCkpIHtcblxuICAgICAgLyogVHJ5IHRvIHBhcnNlICovXG4gICAgICB0cnkge1xuICAgICAgICBwYXJzZWREYXRhID0gSlNPTi5wYXJzZSh1bnBhcnNlZERhdGEpIGFzIFQ7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvciBhcyBTeW50YXhFcnJvcik7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHBhcnNlZERhdGEpO1xuXG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgYW4gaXRlbSBpbiBgbG9jYWxTdG9yYWdlYFxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBkYXRhIFRoZSBpdGVtJ3MgdmFsdWVcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgc2V0KGtleTogc3RyaW5nLCBkYXRhOiB1bmtub3duKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIGxldCBzZXJpYWxpemVkRGF0YTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgICAvKiBDaGVjayBpZiBkYXRhIGNhbiBiZSBzZXJpYWxpemVkICovXG4gICAgY29uc3QgZGF0YVByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKTtcbiAgICBpZiAoKHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JykgJiYgKGRhdGEgIT09IG51bGwpICYmICFBcnJheS5pc0FycmF5KGRhdGEpICYmXG4gICAgISgoZGF0YVByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSkgfHwgKGRhdGFQcm90b3R5cGUgPT09IG51bGwpKSkge1xuICAgICAgcmV0dXJuIHRocm93RXJyb3IobmV3IFNlcmlhbGl6YXRpb25FcnJvcigpKTtcbiAgICB9XG5cbiAgICAvKiBUcnkgdG8gc3RyaW5naWZ5IChjYW4gZmFpbCBvbiBjaXJjdWxhciByZWZlcmVuY2VzKSAqL1xuICAgIHRyeSB7XG4gICAgICBzZXJpYWxpemVkRGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvciBhcyBUeXBlRXJyb3IpO1xuICAgIH1cblxuICAgIC8qIENhbiBmYWlsIGlmIHN0b3JhZ2UgcXVvdGEgaXMgZXhjZWVkZWQgKi9cbiAgICB0cnkge1xuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5wcmVmaXhLZXkoa2V5KSwgc2VyaWFsaXplZERhdGEpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvciBhcyBET01FeGNlcHRpb24pO1xuICAgIH1cblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodW5kZWZpbmVkKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYW4gaXRlbSBpbiBgbG9jYWxTdG9yYWdlYFxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSh0aGlzLnByZWZpeEtleShrZXkpKTtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodW5kZWZpbmVkKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYWxsIGl0ZW1zIGluIGBsb2NhbFN0b3JhZ2VgXG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIGNsZWFyKCk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICBsb2NhbFN0b3JhZ2UuY2xlYXIoKTtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodW5kZWZpbmVkKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwga2V5cyBpbiBgbG9jYWxTdG9yYWdlYFxuICAgKiBOb3RlIHRoZSBvcmRlciBvZiB0aGUga2V5cyBtYXkgYmUgaW5jb25zaXN0ZW50IGluIEZpcmVmb3hcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCBpdGVyYXRpbmcgb24ga2V5c1xuICAgKi9cbiAga2V5cygpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuXG4gICAgLyogQ3JlYXRlIGFuIGBPYnNlcnZhYmxlYCBmcm9tIGtleXMgKi9cbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8c3RyaW5nPigoc3Vic2NyaWJlcikgPT4ge1xuXG4gICAgICAvKiBJdGVyZXRhdGUgb3ZlciBhbGwgdGhlIGluZGV4ZXMgKi9cbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsb2NhbFN0b3JhZ2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG5cbiAgICAgICAgLyogQ2FzdCBhcyB3ZSBhcmUgc3VyZSBpbiB0aGlzIGNhc2UgdGhlIGtleSBpcyBub3QgYG51bGxgICovXG4gICAgICAgIHN1YnNjcmliZXIubmV4dCh0aGlzLmdldFVucHJlZml4ZWRLZXkoaW5kZXgpIGFzIHN0cmluZyk7XG5cbiAgICAgIH1cblxuICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuXG4gICAgfSkucGlwZShcbiAgICAgIC8qIFJlcXVpcmVkIHRvIHdvcmsgbGlrZSBvdGhlciBkYXRhYmFzZXMgd2hpY2ggYXJlIGFzeW5jaHJvbm91cyAqL1xuICAgICAgb2JzZXJ2ZU9uKGFzeW5jU2NoZWR1bGVyKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBrZXkgZXhpc3RzIGluIGBsb2NhbFN0b3JhZ2VgXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0ZWxsaW5nIGlmIHRoZSBrZXkgZXhpc3RzIG9yIG5vdFxuICAgKi9cbiAgaGFzKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICAvKiBJdMOpcmF0ZSBvdmVyIGFsbCBpbmRleGVzIGluIHN0b3JhZ2UgKi9cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbG9jYWxTdG9yYWdlLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuXG4gICAgICBpZiAoa2V5ID09PSB0aGlzLmdldFVucHJlZml4ZWRLZXkoaW5kZXgpKcKge1xuXG4gICAgICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICAgICAgcmV0dXJuIG9mKHRydWUpO1xuXG4gICAgICB9XG5cbiAgICB9XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKGZhbHNlKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbiB1bnByZWZpeGVkIGtleVxuICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2YgdGhlIGtleVxuICAgKiBAcmV0dXJucyBUaGUgdW5wcmVmaXhlZCBrZXkgbmFtZSBpZiBleGlzdHMsIGBudWxsYCBvdGhlcndpc2VcbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnByZWZpeGVkS2V5KGluZGV4OiBudW1iZXIpOiBzdHJpbmcgfCBudWxsIHtcblxuICAgIC8qIEdldCB0aGUga2V5IGluIHN0b3JhZ2U6IG1heSBoYXZlIGEgcHJlZml4ICovXG4gICAgY29uc3QgcHJlZml4ZWRLZXkgPSBsb2NhbFN0b3JhZ2Uua2V5KGluZGV4KTtcblxuICAgIGlmIChwcmVmaXhlZEtleSAhPT0gbnVsbCkge1xuXG4gICAgICAvKiBJZiBubyBwcmVmaXgsIHRoZSBrZXkgaXMgYWxyZWFkeSBnb29kLCBvdGhlcndyaXRlIHN0cmlwIHRoZSBwcmVmaXggKi9cbiAgICAgIHJldHVybiAhdGhpcy5wcmVmaXggPyBwcmVmaXhlZEtleSA6IHByZWZpeGVkS2V5LnN1YnN0cih0aGlzLnByZWZpeC5sZW5ndGgpO1xuXG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgdGhlIHByZWZpeCB0byBhIGtleVxuICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgbmFtZVxuICAgKiBAcmV0dXJucyBUaGUgcHJlZml4ZWQga2V5IG5hbWVcbiAgICovXG4gIHByb3RlY3RlZCBwcmVmaXhLZXkoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuXG4gICAgcmV0dXJuIGAke3RoaXMucHJlZml4fSR7a2V5fWA7XG5cbiAgfVxuXG59XG4iXX0=

@@ -5,81 +5,84 @@ import { __decorate } from "tslib";

import * as i0 from "@angular/core";
let MemoryDatabase = class MemoryDatabase {
constructor() {
let MemoryDatabase = /** @class */ (() => {
let MemoryDatabase = class MemoryDatabase {
constructor() {
/**
* Memory storage
*/
this.memoryStorage = new Map();
}
/**
* Memory storage
* Number of items in memory
*/
this.memoryStorage = new Map();
}
/**
* Number of items in memory
*/
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.size);
}
/**
* Gets an item value in memory
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
const rawData = this.memoryStorage.get(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(rawData);
}
/**
* Sets an item in memory
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
this.memoryStorage.set(key, data);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes an item in memory
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
this.memoryStorage.delete(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes all items in memory
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
this.memoryStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Get all keys in memory
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return from(this.memoryStorage.keys());
}
/**
* Check if a key exists in memory
* @param key Key name
* @returns a RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.has(key));
}
};
MemoryDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function MemoryDatabase_Factory() { return new MemoryDatabase(); }, token: MemoryDatabase, providedIn: "root" });
MemoryDatabase = __decorate([
Injectable({
providedIn: 'root'
})
], MemoryDatabase);
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.size);
}
/**
* Gets an item value in memory
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
const rawData = this.memoryStorage.get(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(rawData);
}
/**
* Sets an item in memory
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
this.memoryStorage.set(key, data);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes an item in memory
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
this.memoryStorage.delete(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes all items in memory
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
this.memoryStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Get all keys in memory
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return from(this.memoryStorage.keys());
}
/**
* Check if a key exists in memory
* @param key Key name
* @returns a RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.has(key));
}
};
MemoryDatabase.ɵprov = i0.ɵɵdefineInjectable({ factory: function MemoryDatabase_Factory() { return new MemoryDatabase(); }, token: MemoryDatabase, providedIn: "root" });
MemoryDatabase = __decorate([
Injectable({
providedIn: 'root'
})
], MemoryDatabase);
return MemoryDatabase;
})();
export { MemoryDatabase };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9kYXRhYmFzZXMvbWVtb3J5LWRhdGFiYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQU81QyxJQUFhLGNBQWMsR0FBM0IsTUFBYSxjQUFjO0lBQTNCO1FBRUU7O1dBRUc7UUFDTyxrQkFBYSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFDO0tBMkZ0RDtJQXpGQzs7T0FFRztJQUNILElBQUksSUFBSTtRQUVOLHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXJDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0YsR0FBRyxDQUFjLEdBQVc7UUFFM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFrQixDQUFDO1FBRTdELHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUVyQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDRixHQUFHLENBQUMsR0FBVyxFQUFFLElBQWE7UUFFN0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRWxDLHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV2QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNGLE1BQU0sQ0FBQyxHQUFXO1FBRWpCLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRS9CLHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV2QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0YsS0FBSztRQUVKLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFM0Isc0VBQXNFO1FBQ3RFLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRXZCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJO1FBRUYsc0NBQXNDO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUV6QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEdBQUcsQ0FBQyxHQUFXO1FBRWIsc0VBQXNFO1FBQ3RFLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFekMsQ0FBQztDQUVGLENBQUE7O0FBaEdZLGNBQWM7SUFIMUIsVUFBVSxDQUFDO1FBQ1YsVUFBVSxFQUFFLE1BQU07S0FDbkIsQ0FBQztHQUNXLGNBQWMsQ0FnRzFCO1NBaEdZLGNBQWMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiwgZnJvbSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBMb2NhbERhdGFiYXNlIH0gZnJvbSAnLi9sb2NhbC1kYXRhYmFzZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE1lbW9yeURhdGFiYXNlIGltcGxlbWVudHMgTG9jYWxEYXRhYmFzZSB7XG5cbiAgLyoqXG4gICAqIE1lbW9yeSBzdG9yYWdlXG4gICAqL1xuICBwcm90ZWN0ZWQgbWVtb3J5U3RvcmFnZSA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaXRlbXMgaW4gbWVtb3J5XG4gICAqL1xuICBnZXQgc2l6ZSgpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuXG4gICAgLyogV3JhcCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzdG9yYWdlcyAqL1xuICAgIHJldHVybiBvZih0aGlzLm1lbW9yeVN0b3JhZ2Uuc2l6ZSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFuIGl0ZW0gdmFsdWUgaW4gbWVtb3J5XG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgVGhlIGl0ZW0ncyB2YWx1ZSBpZiB0aGUga2V5IGV4aXN0cywgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLCB3cmFwcGVkIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICovXG4gICBnZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPiB7XG5cbiAgICBjb25zdCByYXdEYXRhID0gdGhpcy5tZW1vcnlTdG9yYWdlLmdldChrZXkpIGFzIFQgfCB1bmRlZmluZWQ7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHJhd0RhdGEpO1xuXG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhbiBpdGVtIGluIG1lbW9yeVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBkYXRhIFRoZSBpdGVtJ3MgdmFsdWVcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgIHNldChrZXk6IHN0cmluZywgZGF0YTogdW5rbm93bik6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICB0aGlzLm1lbW9yeVN0b3JhZ2Uuc2V0KGtleSwgZGF0YSk7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIGl0ZW0gaW4gbWVtb3J5XG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgIGRlbGV0ZShrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICB0aGlzLm1lbW9yeVN0b3JhZ2UuZGVsZXRlKGtleSk7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFsbCBpdGVtcyBpbiBtZW1vcnlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgIGNsZWFyKCk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICB0aGlzLm1lbW9yeVN0b3JhZ2UuY2xlYXIoKTtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodW5kZWZpbmVkKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwga2V5cyBpbiBtZW1vcnlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCBpdGVyYXRpbmcgb24ga2V5c1xuICAgKi9cbiAga2V5cygpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuXG4gICAgLyogQ3JlYXRlIGFuIGBPYnNlcnZhYmxlYCBmcm9tIGtleXMgKi9cbiAgICByZXR1cm4gZnJvbSh0aGlzLm1lbW9yeVN0b3JhZ2Uua2V5cygpKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEga2V5IGV4aXN0cyBpbiBtZW1vcnlcbiAgICogQHBhcmFtIGtleSBLZXkgbmFtZVxuICAgKiBAcmV0dXJucyBhIFJ4SlMgYE9ic2VydmFibGVgIHRlbGxpbmcgaWYgdGhlIGtleSBleGlzdHMgb3Igbm90XG4gICAqL1xuICBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodGhpcy5tZW1vcnlTdG9yYWdlLmhhcyhrZXkpKTtcblxuICB9XG5cbn1cbiJdfQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9kYXRhYmFzZXMvbWVtb3J5LWRhdGFiYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQU81QztJQUFBLElBQWEsY0FBYyxHQUEzQixNQUFhLGNBQWM7UUFBM0I7WUFFRTs7ZUFFRztZQUNPLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7U0EyRnREO1FBekZDOztXQUVHO1FBQ0gsSUFBSSxJQUFJO1lBRU4sc0VBQXNFO1lBQ3RFLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFckMsQ0FBQztRQUVEOzs7O1dBSUc7UUFDRixHQUFHLENBQWMsR0FBVztZQUUzQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQWtCLENBQUM7WUFFN0Qsc0VBQXNFO1lBQ3RFLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXJCLENBQUM7UUFFRDs7Ozs7V0FLRztRQUNGLEdBQUcsQ0FBQyxHQUFXLEVBQUUsSUFBYTtZQUU3QixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFbEMsc0VBQXNFO1lBQ3RFLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXZCLENBQUM7UUFFRDs7OztXQUlHO1FBQ0YsTUFBTSxDQUFDLEdBQVc7WUFFakIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFL0Isc0VBQXNFO1lBQ3RFLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXZCLENBQUM7UUFFRDs7O1dBR0c7UUFDRixLQUFLO1lBRUosSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUUzQixzRUFBc0U7WUFDdEUsT0FBTyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFdkIsQ0FBQztRQUVEOzs7V0FHRztRQUNILElBQUk7WUFFRixzQ0FBc0M7WUFDdEMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXpDLENBQUM7UUFFRDs7OztXQUlHO1FBQ0gsR0FBRyxDQUFDLEdBQVc7WUFFYixzRUFBc0U7WUFDdEUsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUV6QyxDQUFDO0tBRUYsQ0FBQTs7SUFoR1ksY0FBYztRQUgxQixVQUFVLENBQUM7WUFDVixVQUFVLEVBQUUsTUFBTTtTQUNuQixDQUFDO09BQ1csY0FBYyxDQWdHMUI7eUJBeEdEO0tBd0dDO1NBaEdZLGNBQWMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiwgZnJvbSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBMb2NhbERhdGFiYXNlIH0gZnJvbSAnLi9sb2NhbC1kYXRhYmFzZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE1lbW9yeURhdGFiYXNlIGltcGxlbWVudHMgTG9jYWxEYXRhYmFzZSB7XG5cbiAgLyoqXG4gICAqIE1lbW9yeSBzdG9yYWdlXG4gICAqL1xuICBwcm90ZWN0ZWQgbWVtb3J5U3RvcmFnZSA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaXRlbXMgaW4gbWVtb3J5XG4gICAqL1xuICBnZXQgc2l6ZSgpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuXG4gICAgLyogV3JhcCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzdG9yYWdlcyAqL1xuICAgIHJldHVybiBvZih0aGlzLm1lbW9yeVN0b3JhZ2Uuc2l6ZSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFuIGl0ZW0gdmFsdWUgaW4gbWVtb3J5XG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgVGhlIGl0ZW0ncyB2YWx1ZSBpZiB0aGUga2V5IGV4aXN0cywgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLCB3cmFwcGVkIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICovXG4gICBnZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPiB7XG5cbiAgICBjb25zdCByYXdEYXRhID0gdGhpcy5tZW1vcnlTdG9yYWdlLmdldChrZXkpIGFzIFQgfCB1bmRlZmluZWQ7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHJhd0RhdGEpO1xuXG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhbiBpdGVtIGluIG1lbW9yeVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBkYXRhIFRoZSBpdGVtJ3MgdmFsdWVcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgIHNldChrZXk6IHN0cmluZywgZGF0YTogdW5rbm93bik6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICB0aGlzLm1lbW9yeVN0b3JhZ2Uuc2V0KGtleSwgZGF0YSk7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIGl0ZW0gaW4gbWVtb3J5XG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgIGRlbGV0ZShrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICB0aGlzLm1lbW9yeVN0b3JhZ2UuZGVsZXRlKGtleSk7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFsbCBpdGVtcyBpbiBtZW1vcnlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgIGNsZWFyKCk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICB0aGlzLm1lbW9yeVN0b3JhZ2UuY2xlYXIoKTtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodW5kZWZpbmVkKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwga2V5cyBpbiBtZW1vcnlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCBpdGVyYXRpbmcgb24ga2V5c1xuICAgKi9cbiAga2V5cygpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuXG4gICAgLyogQ3JlYXRlIGFuIGBPYnNlcnZhYmxlYCBmcm9tIGtleXMgKi9cbiAgICByZXR1cm4gZnJvbSh0aGlzLm1lbW9yeVN0b3JhZ2Uua2V5cygpKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEga2V5IGV4aXN0cyBpbiBtZW1vcnlcbiAgICogQHBhcmFtIGtleSBLZXkgbmFtZVxuICAgKiBAcmV0dXJucyBhIFJ4SlMgYE9ic2VydmFibGVgIHRlbGxpbmcgaWYgdGhlIGtleSBleGlzdHMgb3Igbm90XG4gICAqL1xuICBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodGhpcy5tZW1vcnlTdG9yYWdlLmhhcyhrZXkpKTtcblxuICB9XG5cbn1cbiJdfQ==

@@ -1,2 +0,1 @@

var StorageModule_1;
import { __decorate } from "tslib";

@@ -8,32 +7,36 @@ import { NgModule } from '@angular/core';

*/
let StorageModule = StorageModule_1 = class StorageModule {
/**
* Only useful to provide options, otherwise it does nothing.
* **Must be used at initialization, ie. in `AppModule`, and must not be loaded again in another module.**
*
* @example
* NgModule({
* imports: [StorageModule.forRoot({
* LSPrefix: 'custom_',
* })]
* })
* export class AppModule
*/
static forRoot(config) {
return {
ngModule: StorageModule_1,
providers: [
config.LSPrefix ? { provide: LS_PREFIX, useValue: config.LSPrefix } : [],
config.IDBDBName ? { provide: IDB_DB_NAME, useValue: config.IDBDBName } : [],
config.IDBStoreName ? { provide: IDB_STORE_NAME, useValue: config.IDBStoreName } : [],
config.IDBDBVersion ? { provide: IDB_DB_VERSION, useValue: config.IDBDBVersion } : [],
(config.IDBNoWrap === false) ? { provide: IDB_NO_WRAP, useValue: config.IDBNoWrap } : [],
],
};
}
};
StorageModule = StorageModule_1 = __decorate([
NgModule()
], StorageModule);
let StorageModule = /** @class */ (() => {
var StorageModule_1;
let StorageModule = StorageModule_1 = class StorageModule {
/**
* Only useful to provide options, otherwise it does nothing.
* **Must be used at initialization, ie. in `AppModule`, and must not be loaded again in another module.**
*
* @example
* NgModule({
* imports: [StorageModule.forRoot({
* LSPrefix: 'custom_',
* })]
* })
* export class AppModule
*/
static forRoot(config) {
return {
ngModule: StorageModule_1,
providers: [
config.LSPrefix ? { provide: LS_PREFIX, useValue: config.LSPrefix } : [],
config.IDBDBName ? { provide: IDB_DB_NAME, useValue: config.IDBDBName } : [],
config.IDBStoreName ? { provide: IDB_STORE_NAME, useValue: config.IDBStoreName } : [],
config.IDBDBVersion ? { provide: IDB_DB_VERSION, useValue: config.IDBDBVersion } : [],
(config.IDBNoWrap === false) ? { provide: IDB_NO_WRAP, useValue: config.IDBNoWrap } : [],
],
};
}
};
StorageModule = StorageModule_1 = __decorate([
NgModule()
], StorageModule);
return StorageModule;
})();
export { StorageModule };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5tb2R1bGUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LXB3YS9sb2NhbC1zdG9yYWdlLyIsInNvdXJjZXMiOlsibGliL3N0b3JhZ2UubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsT0FBTyxFQUFFLFFBQVEsRUFBdUIsTUFBTSxlQUFlLENBQUM7QUFFOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQWlCLE1BQU0sVUFBVSxDQUFDO0FBRTlHOztHQUVHO0FBRUgsSUFBYSxhQUFhLHFCQUExQixNQUFhLGFBQWE7SUFFeEI7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQXFCO1FBQ2xDLE9BQU87WUFDTCxRQUFRLEVBQUUsZUFBYTtZQUN2QixTQUFTLEVBQUU7Z0JBQ1QsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3hFLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUM1RSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDckYsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3JGLENBQUMsTUFBTSxDQUFDLFNBQVMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7YUFDekY7U0FDRixDQUFDO0lBQ0osQ0FBQztDQUVGLENBQUE7QUEzQlksYUFBYTtJQUR6QixRQUFRLEVBQUU7R0FDRSxhQUFhLENBMkJ6QjtTQTNCWSxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUsIE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgTFNfUFJFRklYLCBJREJfREJfTkFNRSwgSURCX1NUT1JFX05BTUUsIElEQl9EQl9WRVJTSU9OLCBJREJfTk9fV1JBUCwgU3RvcmFnZUNvbmZpZyB9IGZyb20gJy4vdG9rZW5zJztcblxuLyoqXG4gKiBUaGlzIG1vZHVsZSBkb2VzIG5vdCBjb250YWluIGFueXRoaW5nLCBpdCdzIG9ubHkgdXNlZnVsIHRvIHByb3ZpZGUgb3B0aW9ucyB2aWEgYC5mb3JSb290KClgLlxuICovXG5ATmdNb2R1bGUoKVxuZXhwb3J0IGNsYXNzIFN0b3JhZ2VNb2R1bGUge1xuXG4gIC8qKlxuICAgKiBPbmx5IHVzZWZ1bCB0byBwcm92aWRlIG9wdGlvbnMsIG90aGVyd2lzZSBpdCBkb2VzIG5vdGhpbmcuXG4gICAqICoqTXVzdCBiZSB1c2VkIGF0IGluaXRpYWxpemF0aW9uLCBpZS4gaW4gYEFwcE1vZHVsZWAsIGFuZCBtdXN0IG5vdCBiZSBsb2FkZWQgYWdhaW4gaW4gYW5vdGhlciBtb2R1bGUuKipcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogTmdNb2R1bGUoe1xuICAgKiAgIGltcG9ydHM6IFtTdG9yYWdlTW9kdWxlLmZvclJvb3Qoe1xuICAgKiAgICAgTFNQcmVmaXg6ICdjdXN0b21fJyxcbiAgICogICB9KV1cbiAgICogfSlcbiAgICogZXhwb3J0IGNsYXNzIEFwcE1vZHVsZVxuICAgKi9cbiAgc3RhdGljIGZvclJvb3QoY29uZmlnOiBTdG9yYWdlQ29uZmlnKTogTW9kdWxlV2l0aFByb3ZpZGVyczxTdG9yYWdlTW9kdWxlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5nTW9kdWxlOiBTdG9yYWdlTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIGNvbmZpZy5MU1ByZWZpeCA/IHsgcHJvdmlkZTogTFNfUFJFRklYLCB1c2VWYWx1ZTogY29uZmlnLkxTUHJlZml4IH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQkRCTmFtZSA/IHsgcHJvdmlkZTogSURCX0RCX05BTUUsIHVzZVZhbHVlOiBjb25maWcuSURCREJOYW1lIH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQlN0b3JlTmFtZSA/IHsgcHJvdmlkZTogSURCX1NUT1JFX05BTUUsIHVzZVZhbHVlOiBjb25maWcuSURCU3RvcmVOYW1lIH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQkRCVmVyc2lvbiA/IHsgcHJvdmlkZTogSURCX0RCX1ZFUlNJT04sIHVzZVZhbHVlOiBjb25maWcuSURCREJWZXJzaW9uIH0gOiBbXSxcbiAgICAgICAgKGNvbmZpZy5JREJOb1dyYXAgPT09IGZhbHNlKSA/IHsgcHJvdmlkZTogSURCX05PX1dSQVAsIHVzZVZhbHVlOiBjb25maWcuSURCTm9XcmFwIH0gOiBbXSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG59XG4iXX0=
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5tb2R1bGUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LXB3YS9sb2NhbC1zdG9yYWdlLyIsInNvdXJjZXMiOlsibGliL3N0b3JhZ2UubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUF1QixNQUFNLGVBQWUsQ0FBQztBQUU5RCxPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBaUIsTUFBTSxVQUFVLENBQUM7QUFFOUc7O0dBRUc7QUFFSDs7SUFBQSxJQUFhLGFBQWEscUJBQTFCLE1BQWEsYUFBYTtRQUV4Qjs7Ozs7Ozs7Ozs7V0FXRztRQUNILE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBcUI7WUFDbEMsT0FBTztnQkFDTCxRQUFRLEVBQUUsZUFBYTtnQkFDdkIsU0FBUyxFQUFFO29CQUNULE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUN4RSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDNUUsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3JGLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUNyRixDQUFDLE1BQU0sQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO2lCQUN6RjthQUNGLENBQUM7UUFDSixDQUFDO0tBRUYsQ0FBQTtJQTNCWSxhQUFhO1FBRHpCLFFBQVEsRUFBRTtPQUNFLGFBQWEsQ0EyQnpCO0lBQUQsb0JBQUM7S0FBQTtTQTNCWSxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUsIE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgTFNfUFJFRklYLCBJREJfREJfTkFNRSwgSURCX1NUT1JFX05BTUUsIElEQl9EQl9WRVJTSU9OLCBJREJfTk9fV1JBUCwgU3RvcmFnZUNvbmZpZyB9IGZyb20gJy4vdG9rZW5zJztcblxuLyoqXG4gKiBUaGlzIG1vZHVsZSBkb2VzIG5vdCBjb250YWluIGFueXRoaW5nLCBpdCdzIG9ubHkgdXNlZnVsIHRvIHByb3ZpZGUgb3B0aW9ucyB2aWEgYC5mb3JSb290KClgLlxuICovXG5ATmdNb2R1bGUoKVxuZXhwb3J0IGNsYXNzIFN0b3JhZ2VNb2R1bGUge1xuXG4gIC8qKlxuICAgKiBPbmx5IHVzZWZ1bCB0byBwcm92aWRlIG9wdGlvbnMsIG90aGVyd2lzZSBpdCBkb2VzIG5vdGhpbmcuXG4gICAqICoqTXVzdCBiZSB1c2VkIGF0IGluaXRpYWxpemF0aW9uLCBpZS4gaW4gYEFwcE1vZHVsZWAsIGFuZCBtdXN0IG5vdCBiZSBsb2FkZWQgYWdhaW4gaW4gYW5vdGhlciBtb2R1bGUuKipcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogTmdNb2R1bGUoe1xuICAgKiAgIGltcG9ydHM6IFtTdG9yYWdlTW9kdWxlLmZvclJvb3Qoe1xuICAgKiAgICAgTFNQcmVmaXg6ICdjdXN0b21fJyxcbiAgICogICB9KV1cbiAgICogfSlcbiAgICogZXhwb3J0IGNsYXNzIEFwcE1vZHVsZVxuICAgKi9cbiAgc3RhdGljIGZvclJvb3QoY29uZmlnOiBTdG9yYWdlQ29uZmlnKTogTW9kdWxlV2l0aFByb3ZpZGVyczxTdG9yYWdlTW9kdWxlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5nTW9kdWxlOiBTdG9yYWdlTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIGNvbmZpZy5MU1ByZWZpeCA/IHsgcHJvdmlkZTogTFNfUFJFRklYLCB1c2VWYWx1ZTogY29uZmlnLkxTUHJlZml4IH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQkRCTmFtZSA/IHsgcHJvdmlkZTogSURCX0RCX05BTUUsIHVzZVZhbHVlOiBjb25maWcuSURCREJOYW1lIH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQlN0b3JlTmFtZSA/IHsgcHJvdmlkZTogSURCX1NUT1JFX05BTUUsIHVzZVZhbHVlOiBjb25maWcuSURCU3RvcmVOYW1lIH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQkRCVmVyc2lvbiA/IHsgcHJvdmlkZTogSURCX0RCX1ZFUlNJT04sIHVzZVZhbHVlOiBjb25maWcuSURCREJWZXJzaW9uIH0gOiBbXSxcbiAgICAgICAgKGNvbmZpZy5JREJOb1dyYXAgPT09IGZhbHNlKSA/IHsgcHJvdmlkZTogSURCX05PX1dSQVAsIHVzZVZhbHVlOiBjb25maWcuSURCTm9XcmFwIH0gOiBbXSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG59XG4iXX0=

@@ -7,84 +7,87 @@ import { __decorate } from "tslib";

import * as i1 from "./storage-map.service";
let LocalStorage = class LocalStorage {
/* Use the `StorageMap` service to avoid code duplication */
constructor(storageMap) {
this.storageMap = storageMap;
}
/**
* Number of items in storage wrapped in an `Observable`
*
* @example
* this.localStorage.length.subscribe((length) => {
* console.log(length);
* });
*/
get length() {
return this.storageMap.size;
}
getItem(key, schema) {
if (schema) {
/* Backward compatibility with version <= 7 */
const schemaFinal = ('schema' in schema) ? schema.schema : schema;
return this.storageMap.get(key, schemaFinal).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
let LocalStorage = /** @class */ (() => {
let LocalStorage = class LocalStorage {
/* Use the `StorageMap` service to avoid code duplication */
constructor(storageMap) {
this.storageMap = storageMap;
}
else {
return this.storageMap.get(key).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
/**
* Number of items in storage wrapped in an `Observable`
*
* @example
* this.localStorage.length.subscribe((length) => {
* console.log(length);
* });
*/
get length() {
return this.storageMap.size;
}
}
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.set('key', 'value').subscribe(() => {});
*/
setItem(key, data, schema) {
return this.storageMap.set(key, data, schema).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.delete('key').subscribe(() => {});
*/
removeItem(key) {
return this.storageMap.delete(key).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.clear().subscribe(() => {});
*/
clear() {
return this.storageMap.clear().pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
};
LocalStorage.ctorParameters = () => [
{ type: StorageMap }
];
LocalStorage.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalStorage_Factory() { return new LocalStorage(i0.ɵɵinject(i1.StorageMap)); }, token: LocalStorage, providedIn: "root" });
LocalStorage = __decorate([
Injectable({
providedIn: 'root'
})
], LocalStorage);
getItem(key, schema) {
if (schema) {
/* Backward compatibility with version <= 7 */
const schemaFinal = ('schema' in schema) ? schema.schema : schema;
return this.storageMap.get(key, schemaFinal).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
}
else {
return this.storageMap.get(key).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
}
}
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.set('key', 'value').subscribe(() => {});
*/
setItem(key, data, schema) {
return this.storageMap.set(key, data, schema).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.delete('key').subscribe(() => {});
*/
removeItem(key) {
return this.storageMap.delete(key).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.clear().subscribe(() => {});
*/
clear() {
return this.storageMap.clear().pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
};
LocalStorage.ctorParameters = () => [
{ type: StorageMap }
];
LocalStorage.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalStorage_Factory() { return new LocalStorage(i0.ɵɵinject(i1.StorageMap)); }, token: LocalStorage, providedIn: "root" });
LocalStorage = __decorate([
Injectable({
providedIn: 'root'
})
], LocalStorage);
return LocalStorage;
})();
export { LocalStorage };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtc3RvcmFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9zdG9yYWdlcy9sb2NhbC1zdG9yYWdlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQU01QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7OztBQUtuRCxJQUFhLFlBQVksR0FBekIsTUFBYSxZQUFZO0lBZ0J2Qiw0REFBNEQ7SUFDNUQsWUFBc0IsVUFBc0I7UUFBdEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtJQUFHLENBQUM7SUFmaEQ7Ozs7Ozs7T0FPRztJQUNILElBQUksTUFBTTtRQUVSLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFFOUIsQ0FBQztJQWtERCxPQUFPLENBQWMsR0FBVyxFQUFFLE1BQXdEO1FBRXhGLElBQUksTUFBTSxFQUFFO1lBRVYsOENBQThDO1lBQzlDLE1BQU0sV0FBVyxHQUFlLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFFOUUsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBSSxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUMsSUFBSTtZQUNsRCx3RUFBd0U7WUFDeEUsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FDckQsQ0FBQztTQUVIO2FBQU07WUFFTCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUk7WUFDbEMsd0VBQXdFO1lBQ3hFLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQ3JELENBQUM7U0FFSDtJQUVILENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsT0FBTyxDQUFDLEdBQVcsRUFBRSxJQUFhLEVBQUUsTUFBbUI7UUFFckQsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUk7UUFDaEQsMEVBQTBFO1FBQzFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FDWixDQUFDO0lBRUosQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxVQUFVLENBQUMsR0FBVztRQUVwQixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUk7UUFDckMsMEVBQTBFO1FBQzFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FDWixDQUFDO0lBRUosQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILEtBQUs7UUFFSCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSTtRQUNqQywwRUFBMEU7UUFDMUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUNaLENBQUM7SUFFSixDQUFDO0NBRUYsQ0FBQTs7WUEzSG1DLFVBQVU7OztBQWpCakMsWUFBWTtJQUh4QixVQUFVLENBQUM7UUFDVixVQUFVLEVBQUUsTUFBTTtLQUNuQixDQUFDO0dBQ1csWUFBWSxDQTRJeEI7U0E1SVksWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcFRvLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIEpTT05TY2hlbWEsIEpTT05TY2hlbWFCb29sZWFuLCBKU09OU2NoZW1hSW50ZWdlcixcbiAgSlNPTlNjaGVtYU51bWJlciwgSlNPTlNjaGVtYVN0cmluZywgSlNPTlNjaGVtYUFycmF5T2Zcbn0gZnJvbSAnLi4vdmFsaWRhdGlvbi9qc29uLXNjaGVtYSc7XG5pbXBvcnQgeyBTdG9yYWdlTWFwIH0gZnJvbSAnLi9zdG9yYWdlLW1hcC5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTG9jYWxTdG9yYWdlIHtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIGl0ZW1zIGluIHN0b3JhZ2Ugd3JhcHBlZCBpbiBhbiBgT2JzZXJ2YWJsZWBcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5sb2NhbFN0b3JhZ2UubGVuZ3RoLnN1YnNjcmliZSgobGVuZ3RoKSA9PiB7XG4gICAqICAgY29uc29sZS5sb2cobGVuZ3RoKTtcbiAgICogfSk7XG4gICAqL1xuICBnZXQgbGVuZ3RoKCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG5cbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlTWFwLnNpemU7XG5cbiAgfVxuXG4gIC8qIFVzZSB0aGUgYFN0b3JhZ2VNYXBgIHNlcnZpY2UgdG8gYXZvaWQgY29kZSBkdXBsaWNhdGlvbiAqL1xuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgc3RvcmFnZU1hcDogU3RvcmFnZU1hcCkge31cblxuICAvKipcbiAgICogR2V0IGFuIGl0ZW0gdmFsdWUgaW4gc3RvcmFnZS5cbiAgICogVGhlIHNpZ25hdHVyZSBoYXMgbWFueSBvdmVybG9hZHMgZHVlIHRvIHZhbGlkYXRpb24sICoqcGxlYXNlIHJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uLioqXG4gICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvYmxvYi9tYXN0ZXIvZG9jcy9WQUxJREFUSU9OLm1kfVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBzY2hlbWEgT3B0aW9uYWwgSlNPTiBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIGRhdGEuXG4gICAqICoqTm90ZSB5b3UgbXVzdCBwYXNzIHRoZSBzY2hlbWEgZGlyZWN0bHkgYXMgdGhlIHNlY29uZCBhcmd1bWVudC4qKlxuICAgKiAqKlBhc3NpbmcgdGhlIHNjaGVtYSBpbiBhbiBvYmplY3QgYHsgc2NoZW1hIH1gIGlzIGRlcHJlY2F0ZWQgYW5kIG9ubHkgaGVyZSoqXG4gICAqICoqZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IGl0IHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uLioqXG4gICAqIEByZXR1cm5zIFRoZSBpdGVtJ3MgdmFsdWUgaWYgdGhlIGtleSBleGlzdHMsIGBudWxsYCBvdGhlcndpc2UsIHdyYXBwZWQgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLmxvY2FsU3RvcmFnZS5nZXQoJ2tleScsIHsgdHlwZTogJ3N0cmluZycgfSkuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICogICByZXN1bHQ7IC8vIHN0cmluZyBvciBudWxsXG4gICAqIH0pO1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBpbnRlcmZhY2UgVXNlciB7XG4gICAqICAgZmlyc3ROYW1lOiBzdHJpbmc7XG4gICAqICAgbGFzdE5hbWU/OiBzdHJpbmc7XG4gICAqIH1cbiAgICpcbiAgICogY29uc3Qgc2NoZW1hID0ge1xuICAgKiAgIHR5cGU6ICdvYmplY3QnLFxuICAgKiAgIHByb3BlcnRpZXM6IHtcbiAgICogICAgIGZpcnN0TmFtZTogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgKiAgICAgbGFzdE5hbWU6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICogICB9LFxuICAgKiAgIHJlcXVpcmVkOiBbJ2ZpcnN0TmFtZSddXG4gICAqIH07XG4gICAqXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLmdldDxVc2VyPigndXNlcicsIHNjaGVtYSkuc3Vic2NyaWJlKCh1c2VyKSA9PiB7XG4gICAqICAgaWYgKHVzZXIpIHtcbiAgICogICAgIHVzZXIuZmlyc3ROYW1lO1xuICAgKiAgIH1cbiAgICogfSk7XG4gICAqL1xuICBnZXRJdGVtPFQgPSBzdHJpbmc+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFTdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZyB8IG51bGw+O1xuICBnZXRJdGVtPFQgPSBudW1iZXI+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFJbnRlZ2VywqB8IEpTT05TY2hlbWFOdW1iZXIpOiBPYnNlcnZhYmxlPG51bWJlciB8IG51bGw+O1xuICBnZXRJdGVtPFQgPSBib29sZWFuPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQm9vbGVhbik6IE9ic2VydmFibGU8Ym9vbGVhbiB8IG51bGw+O1xuICBnZXRJdGVtPFQgPSBzdHJpbmdbXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYVN0cmluZz4pOiBPYnNlcnZhYmxlPHN0cmluZ1tdIHwgbnVsbD47XG4gIGdldEl0ZW08VCA9IG51bWJlcltdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hSW50ZWdlcsKgfCBKU09OU2NoZW1hTnVtYmVyPik6IE9ic2VydmFibGU8bnVtYmVyW10gfCBudWxsPjtcbiAgZ2V0SXRlbTxUID0gYm9vbGVhbltdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hQm9vbGVhbj4pOiBPYnNlcnZhYmxlPGJvb2xlYW5bXSB8IG51bGw+O1xuICBnZXRJdGVtPFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hIHwgeyBzY2hlbWE6IEpTT05TY2hlbWEgfSk6IE9ic2VydmFibGU8VCB8IG51bGw+O1xuICBnZXRJdGVtPFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8dW5rbm93bj47XG4gIGdldEl0ZW08VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBzY2hlbWE/OiBKU09OU2NoZW1hIHwgeyBzY2hlbWE6IEpTT05TY2hlbWEgfSB8IHVuZGVmaW5lZCk6IE9ic2VydmFibGU8dW5rbm93bj4ge1xuXG4gICAgaWYgKHNjaGVtYSkge1xuXG4gICAgICAvKiBCYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggdmVyc2lvbiA8PSA3ICovXG4gICAgICBjb25zdCBzY2hlbWFGaW5hbDogSlNPTlNjaGVtYSA9ICgnc2NoZW1hJyBpbiBzY2hlbWEpID8gc2NoZW1hLnNjaGVtYSA6IHNjaGVtYTtcblxuICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZU1hcC5nZXQ8VD4oa2V5LCBzY2hlbWFGaW5hbCkucGlwZShcbiAgICAgICAgLyogVHJhbnNmb3JtIGB1bmRlZmluZWRgIGludG8gYG51bGxgIHRvIGFsaWduIHdpdGggYGxvY2FsU3RvcmFnZWAgQVBJICovXG4gICAgICAgIG1hcCgodmFsdWUpID0+ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogbnVsbCksXG4gICAgICApO1xuXG4gICAgfSBlbHNlIHtcblxuICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZU1hcC5nZXQoa2V5KS5waXBlKFxuICAgICAgICAvKiBUcmFuc2Zvcm0gYHVuZGVmaW5lZGAgaW50byBgbnVsbGAgdG8gYWxpZ24gd2l0aCBgbG9jYWxTdG9yYWdlYCBBUEkgKi9cbiAgICAgICAgbWFwKCh2YWx1ZSkgPT4gKHZhbHVlICE9PSB1bmRlZmluZWQpID8gdmFsdWUgOiBudWxsKSxcbiAgICAgICk7XG5cbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYW4gaXRlbSBpbiBzdG9yYWdlLlxuICAgKiBOb3RlIHRoYXQgc2V0dGluZyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgd2lsbCByZW1vdmUgdGhlIGl0ZW0gdG8gYXZvaWQgc29tZSBicm93c2VycyBpc3N1ZXMuXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHBhcmFtIGRhdGEgVGhlIGl0ZW0ncyB2YWx1ZVxuICAgKiBAcGFyYW0gc2NoZW1hIE9wdGlvbmFsIEpTT04gc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBkYXRhXG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5sb2NhbFN0b3JhZ2Uuc2V0KCdrZXknLCAndmFsdWUnKS5zdWJzY3JpYmUoKCkgPT4ge30pO1xuICAgKi9cbiAgc2V0SXRlbShrZXk6IHN0cmluZywgZGF0YTogdW5rbm93biwgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZU1hcC5zZXQoa2V5LCBkYXRhLCBzY2hlbWEpLnBpcGUoXG4gICAgICAvKiBUcmFuc2Zvcm0gYHVuZGVmaW5lZGAgaW50byBgdHJ1ZWAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCB2NyAqL1xuICAgICAgbWFwVG8odHJ1ZSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhbiBpdGVtIGluIHN0b3JhZ2VcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLmRlbGV0ZSgna2V5Jykuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIHJlbW92ZUl0ZW0oa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VNYXAuZGVsZXRlKGtleSkucGlwZShcbiAgICAgIC8qIFRyYW5zZm9ybSBgdW5kZWZpbmVkYCBpbnRvIGB0cnVlYCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHY3ICovXG4gICAgICBtYXBUbyh0cnVlKSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGFsbCBpdGVtcyBpbiBzdG9yYWdlXG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5sb2NhbFN0b3JhZ2UuY2xlYXIoKS5zdWJzY3JpYmUoKCkgPT4ge30pO1xuICAgKi9cbiAgY2xlYXIoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlTWFwLmNsZWFyKCkucGlwZShcbiAgICAgIC8qIFRyYW5zZm9ybSBgdW5kZWZpbmVkYCBpbnRvIGB0cnVlYCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHY3ICovXG4gICAgICBtYXBUbyh0cnVlKSxcbiAgICApO1xuXG4gIH1cblxufVxuIl19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtc3RvcmFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1wd2EvbG9jYWwtc3RvcmFnZS8iLCJzb3VyY2VzIjpbImxpYi9zdG9yYWdlcy9sb2NhbC1zdG9yYWdlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQU01QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7OztBQUtuRDtJQUFBLElBQWEsWUFBWSxHQUF6QixNQUFhLFlBQVk7UUFnQnZCLDREQUE0RDtRQUM1RCxZQUFzQixVQUFzQjtZQUF0QixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQUcsQ0FBQztRQWZoRDs7Ozs7OztXQU9HO1FBQ0gsSUFBSSxNQUFNO1lBRVIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztRQUU5QixDQUFDO1FBa0RELE9BQU8sQ0FBYyxHQUFXLEVBQUUsTUFBd0Q7WUFFeEYsSUFBSSxNQUFNLEVBQUU7Z0JBRVYsOENBQThDO2dCQUM5QyxNQUFNLFdBQVcsR0FBZSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO2dCQUU5RSxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFJLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQyxJQUFJO2dCQUNsRCx3RUFBd0U7Z0JBQ3hFLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQ3JELENBQUM7YUFFSDtpQkFBTTtnQkFFTCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUk7Z0JBQ2xDLHdFQUF3RTtnQkFDeEUsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FDckQsQ0FBQzthQUVIO1FBRUgsQ0FBQztRQUVEOzs7Ozs7Ozs7O1dBVUc7UUFDSCxPQUFPLENBQUMsR0FBVyxFQUFFLElBQWEsRUFBRSxNQUFtQjtZQUVyRCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsSUFBSTtZQUNoRCwwRUFBMEU7WUFDMUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUNaLENBQUM7UUFFSixDQUFDO1FBRUQ7Ozs7Ozs7V0FPRztRQUNILFVBQVUsQ0FBQyxHQUFXO1lBRXBCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSTtZQUNyQywwRUFBMEU7WUFDMUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUNaLENBQUM7UUFFSixDQUFDO1FBRUQ7Ozs7OztXQU1HO1FBQ0gsS0FBSztZQUVILE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxJQUFJO1lBQ2pDLDBFQUEwRTtZQUMxRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQ1osQ0FBQztRQUVKLENBQUM7S0FFRixDQUFBOztnQkEzSG1DLFVBQVU7OztJQWpCakMsWUFBWTtRQUh4QixVQUFVLENBQUM7WUFDVixVQUFVLEVBQUUsTUFBTTtTQUNuQixDQUFDO09BQ1csWUFBWSxDQTRJeEI7dUJBekpEO0tBeUpDO1NBNUlZLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXBUbywgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge1xuICBKU09OU2NoZW1hLCBKU09OU2NoZW1hQm9vbGVhbiwgSlNPTlNjaGVtYUludGVnZXIsXG4gIEpTT05TY2hlbWFOdW1iZXIsIEpTT05TY2hlbWFTdHJpbmcsIEpTT05TY2hlbWFBcnJheU9mXG59IGZyb20gJy4uL3ZhbGlkYXRpb24vanNvbi1zY2hlbWEnO1xuaW1wb3J0IHsgU3RvcmFnZU1hcCB9IGZyb20gJy4vc3RvcmFnZS1tYXAuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIExvY2FsU3RvcmFnZSB7XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBpdGVtcyBpbiBzdG9yYWdlIHdyYXBwZWQgaW4gYW4gYE9ic2VydmFibGVgXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLmxlbmd0aC5zdWJzY3JpYmUoKGxlbmd0aCkgPT4ge1xuICAgKiAgIGNvbnNvbGUubG9nKGxlbmd0aCk7XG4gICAqIH0pO1xuICAgKi9cbiAgZ2V0IGxlbmd0aCgpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZU1hcC5zaXplO1xuXG4gIH1cblxuICAvKiBVc2UgdGhlIGBTdG9yYWdlTWFwYCBzZXJ2aWNlIHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24gKi9cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHN0b3JhZ2VNYXA6IFN0b3JhZ2VNYXApIHt9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBpdGVtIHZhbHVlIGluIHN0b3JhZ2UuXG4gICAqIFRoZSBzaWduYXR1cmUgaGFzIG1hbnkgb3ZlcmxvYWRzIGR1ZSB0byB2YWxpZGF0aW9uLCAqKnBsZWFzZSByZWZlciB0byB0aGUgZG9jdW1lbnRhdGlvbi4qKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFzdGVyL2RvY3MvVkFMSURBVElPTi5tZH1cbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gc2NoZW1hIE9wdGlvbmFsIEpTT04gc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBkYXRhLlxuICAgKiAqKk5vdGUgeW91IG11c3QgcGFzcyB0aGUgc2NoZW1hIGRpcmVjdGx5IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQuKipcbiAgICogKipQYXNzaW5nIHRoZSBzY2hlbWEgaW4gYW4gb2JqZWN0IGB7IHNjaGVtYSB9YCBpcyBkZXByZWNhdGVkIGFuZCBvbmx5IGhlcmUqKlxuICAgKiAqKmZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5OiBpdCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi4qKlxuICAgKiBAcmV0dXJucyBUaGUgaXRlbSdzIHZhbHVlIGlmIHRoZSBrZXkgZXhpc3RzLCBgbnVsbGAgb3RoZXJ3aXNlLCB3cmFwcGVkIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5sb2NhbFN0b3JhZ2UuZ2V0KCdrZXknLCB7IHR5cGU6ICdzdHJpbmcnIH0pLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAqICAgcmVzdWx0OyAvLyBzdHJpbmcgb3IgbnVsbFxuICAgKiB9KTtcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaW50ZXJmYWNlIFVzZXIge1xuICAgKiAgIGZpcnN0TmFtZTogc3RyaW5nO1xuICAgKiAgIGxhc3ROYW1lPzogc3RyaW5nO1xuICAgKiB9XG4gICAqXG4gICAqIGNvbnN0IHNjaGVtYSA9IHtcbiAgICogICB0eXBlOiAnb2JqZWN0JyxcbiAgICogICBwcm9wZXJ0aWVzOiB7XG4gICAqICAgICBmaXJzdE5hbWU6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICogICAgIGxhc3ROYW1lOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAqICAgfSxcbiAgICogICByZXF1aXJlZDogWydmaXJzdE5hbWUnXVxuICAgKiB9O1xuICAgKlxuICAgKiB0aGlzLmxvY2FsU3RvcmFnZS5nZXQ8VXNlcj4oJ3VzZXInLCBzY2hlbWEpLnN1YnNjcmliZSgodXNlcikgPT4ge1xuICAgKiAgIGlmICh1c2VyKSB7XG4gICAqICAgICB1c2VyLmZpcnN0TmFtZTtcbiAgICogICB9XG4gICAqIH0pO1xuICAgKi9cbiAgZ2V0SXRlbTxUID0gc3RyaW5nPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hU3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmcgfCBudWxsPjtcbiAgZ2V0SXRlbTxUID0gbnVtYmVyPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hSW50ZWdlcsKgfCBKU09OU2NoZW1hTnVtYmVyKTogT2JzZXJ2YWJsZTxudW1iZXIgfCBudWxsPjtcbiAgZ2V0SXRlbTxUID0gYm9vbGVhbj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUJvb2xlYW4pOiBPYnNlcnZhYmxlPGJvb2xlYW4gfCBudWxsPjtcbiAgZ2V0SXRlbTxUID0gc3RyaW5nW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFTdHJpbmc+KTogT2JzZXJ2YWJsZTxzdHJpbmdbXSB8IG51bGw+O1xuICBnZXRJdGVtPFQgPSBudW1iZXJbXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYUludGVnZXLCoHwgSlNPTlNjaGVtYU51bWJlcj4pOiBPYnNlcnZhYmxlPG51bWJlcltdIHwgbnVsbD47XG4gIGdldEl0ZW08VCA9IGJvb2xlYW5bXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYUJvb2xlYW4+KTogT2JzZXJ2YWJsZTxib29sZWFuW10gfCBudWxsPjtcbiAgZ2V0SXRlbTxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYSB8IHsgc2NoZW1hOiBKU09OU2NoZW1hIH0pOiBPYnNlcnZhYmxlPFQgfCBudWxsPjtcbiAgZ2V0SXRlbTxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHNjaGVtYT86IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPHVua25vd24+O1xuICBnZXRJdGVtPFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hPzogSlNPTlNjaGVtYSB8IHsgc2NoZW1hOiBKU09OU2NoZW1hIH0gfCB1bmRlZmluZWQpOiBPYnNlcnZhYmxlPHVua25vd24+IHtcblxuICAgIGlmIChzY2hlbWEpIHtcblxuICAgICAgLyogQmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHZlcnNpb24gPD0gNyAqL1xuICAgICAgY29uc3Qgc2NoZW1hRmluYWw6IEpTT05TY2hlbWEgPSAoJ3NjaGVtYScgaW4gc2NoZW1hKSA/IHNjaGVtYS5zY2hlbWEgOiBzY2hlbWE7XG5cbiAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2VNYXAuZ2V0PFQ+KGtleSwgc2NoZW1hRmluYWwpLnBpcGUoXG4gICAgICAgIC8qIFRyYW5zZm9ybSBgdW5kZWZpbmVkYCBpbnRvIGBudWxsYCB0byBhbGlnbiB3aXRoIGBsb2NhbFN0b3JhZ2VgIEFQSSAqL1xuICAgICAgICBtYXAoKHZhbHVlKSA9PiAodmFsdWUgIT09IHVuZGVmaW5lZCkgPyB2YWx1ZSA6IG51bGwpLFxuICAgICAgKTtcblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2VNYXAuZ2V0KGtleSkucGlwZShcbiAgICAgICAgLyogVHJhbnNmb3JtIGB1bmRlZmluZWRgIGludG8gYG51bGxgIHRvIGFsaWduIHdpdGggYGxvY2FsU3RvcmFnZWAgQVBJICovXG4gICAgICAgIG1hcCgodmFsdWUpID0+ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogbnVsbCksXG4gICAgICApO1xuXG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogU2V0IGFuIGl0ZW0gaW4gc3RvcmFnZS5cbiAgICogTm90ZSB0aGF0IHNldHRpbmcgYG51bGxgIG9yIGB1bmRlZmluZWRgIHdpbGwgcmVtb3ZlIHRoZSBpdGVtIHRvIGF2b2lkIHNvbWUgYnJvd3NlcnMgaXNzdWVzLlxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBkYXRhIFRoZSBpdGVtJ3MgdmFsdWVcbiAgICogQHBhcmFtIHNjaGVtYSBPcHRpb25hbCBKU09OIHNjaGVtYSB0byB2YWxpZGF0ZSB0aGUgZGF0YVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLnNldCgna2V5JywgJ3ZhbHVlJykuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIHNldEl0ZW0oa2V5OiBzdHJpbmcsIGRhdGE6IHVua25vd24sIHNjaGVtYT86IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VNYXAuc2V0KGtleSwgZGF0YSwgc2NoZW1hKS5waXBlKFxuICAgICAgLyogVHJhbnNmb3JtIGB1bmRlZmluZWRgIGludG8gYHRydWVgIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggdjcgKi9cbiAgICAgIG1hcFRvKHRydWUpLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYW4gaXRlbSBpbiBzdG9yYWdlXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLmxvY2FsU3RvcmFnZS5kZWxldGUoJ2tleScpLnN1YnNjcmliZSgoKSA9PiB7fSk7XG4gICAqL1xuICByZW1vdmVJdGVtKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlTWFwLmRlbGV0ZShrZXkpLnBpcGUoXG4gICAgICAvKiBUcmFuc2Zvcm0gYHVuZGVmaW5lZGAgaW50byBgdHJ1ZWAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCB2NyAqL1xuICAgICAgbWFwVG8odHJ1ZSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhbGwgaXRlbXMgaW4gc3RvcmFnZVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMubG9jYWxTdG9yYWdlLmNsZWFyKCkuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIGNsZWFyKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZU1hcC5jbGVhcigpLnBpcGUoXG4gICAgICAvKiBUcmFuc2Zvcm0gYHVuZGVmaW5lZGAgaW50byBgdHJ1ZWAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCB2NyAqL1xuICAgICAgbWFwVG8odHJ1ZSksXG4gICAgKTtcblxuICB9XG5cbn1cbiJdfQ==

@@ -17,282 +17,285 @@ import { __decorate, __param } from "tslib";

import * as i3 from "../tokens";
let StorageMap = class StorageMap {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param database Storage to use
* @param jsonValidator Validator service
* @param LSPrefix Prefix for `localStorage` keys to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(database, jsonValidator = new JSONValidator(), LSPrefix = '') {
this.database = database;
this.jsonValidator = jsonValidator;
this.LSPrefix = LSPrefix;
this.notifiers = new Map();
}
/**
* **Number of items** in storage, wrapped in an `Observable`.
*
* @example
* this.storageMap.size.subscribe((size) => {
* console.log(size);
* });
*/
get size() {
return this.database.size
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.size));
}
/**
* Tells you which storage engine is used. *Only useful for interoperability.*
* Note that due to some browsers issues in some special contexts
* (Firefox private mode and Safari cross-origin iframes),
* **this information may be wrong at initialization,**
* as the storage could fallback from `indexedDB` to `localStorage`
* only after a first read or write operation.
* @returns Storage engine used
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {}
*/
get backingEngine() {
if (this.database instanceof IndexedDBDatabase) {
return 'indexedDB';
let StorageMap = /** @class */ (() => {
let StorageMap = class StorageMap {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param database Storage to use
* @param jsonValidator Validator service
* @param LSPrefix Prefix for `localStorage` keys to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(database, jsonValidator = new JSONValidator(), LSPrefix = '') {
this.database = database;
this.jsonValidator = jsonValidator;
this.LSPrefix = LSPrefix;
this.notifiers = new Map();
}
else if (this.database instanceof LocalStorageDatabase) {
return 'localStorage';
/**
* **Number of items** in storage, wrapped in an `Observable`.
*
* @example
* this.storageMap.size.subscribe((size) => {
* console.log(size);
* });
*/
get size() {
return this.database.size
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.size));
}
else if (this.database instanceof MemoryDatabase) {
return 'memory';
/**
* Tells you which storage engine is used. *Only useful for interoperability.*
* Note that due to some browsers issues in some special contexts
* (Firefox private mode and Safari cross-origin iframes),
* **this information may be wrong at initialization,**
* as the storage could fallback from `indexedDB` to `localStorage`
* only after a first read or write operation.
* @returns Storage engine used
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {}
*/
get backingEngine() {
if (this.database instanceof IndexedDBDatabase) {
return 'indexedDB';
}
else if (this.database instanceof LocalStorageDatabase) {
return 'localStorage';
}
else if (this.database instanceof MemoryDatabase) {
return 'memory';
}
else {
return 'unknown';
}
}
else {
return 'unknown';
/**
* Info about `indexedDB` database. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version.
* **Values will be empty if the storage is not `indexedDB`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {
* const { database, store, version } = this.storageMap.backingStore;
* }
*/
get backingStore() {
return (this.database instanceof IndexedDBDatabase) ?
this.database.backingStore :
{ database: '', store: '', version: 0 };
}
}
/**
* Info about `indexedDB` database. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version.
* **Values will be empty if the storage is not `indexedDB`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {
* const { database, store, version } = this.storageMap.backingStore;
* }
*/
get backingStore() {
return (this.database instanceof IndexedDBDatabase) ?
this.database.backingStore :
{ database: '', store: '', version: 0 };
}
/**
* Info about `localStorage` fallback storage. *Only useful for interoperability.*
* @returns `localStorage` prefix.
* **Values will be empty if the storage is not `localStorage`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'localStorage') {
* const { prefix } = this.storageMap.fallbackBackingStore;
* }
*/
get fallbackBackingStore() {
return (this.database instanceof LocalStorageDatabase) ?
{ prefix: this.database.prefix } :
{ prefix: '' };
}
get(key, schema) {
/* Get the data in storage */
return this.database.get(key).pipe(
/* Check if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.get(key)), mergeMap((data) => {
/* No need to validate if the data is empty */
if ((data === undefined) || (data === null)) {
return of(undefined);
}
else if (schema) {
/* Validate data against a JSON schema if provided */
if (!this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
/**
* Info about `localStorage` fallback storage. *Only useful for interoperability.*
* @returns `localStorage` prefix.
* **Values will be empty if the storage is not `localStorage`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'localStorage') {
* const { prefix } = this.storageMap.fallbackBackingStore;
* }
*/
get fallbackBackingStore() {
return (this.database instanceof LocalStorageDatabase) ?
{ prefix: this.database.prefix } :
{ prefix: '' };
}
get(key, schema) {
/* Get the data in storage */
return this.database.get(key).pipe(
/* Check if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.get(key)), mergeMap((data) => {
/* No need to validate if the data is empty */
if ((data === undefined) || (data === null)) {
return of(undefined);
}
/* Data have been checked, so it's OK to cast */
else if (schema) {
/* Validate data against a JSON schema if provided */
if (!this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
}
/* Data have been checked, so it's OK to cast */
return of(data);
}
/* Cast to unknown as the data wasn't checked */
return of(data);
}
/* Cast to unknown as the data wasn't checked */
return of(data);
}));
}
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.set('key', 'value').subscribe(() => {});
*/
set(key, data, schema) {
/* Storing `undefined` or `null` is useless and can cause issues in `indexedDb` in some browsers,
* so removing item instead for all storages to have a consistent API */
if ((data === undefined) || (data === null)) {
return this.delete(key);
}));
}
/* Validate data against a JSON schema if provided */
if (schema && !this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
}
return this.database.set(key, data).pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.set(key, data)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, data); }));
}
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.delete('key').subscribe(() => {});
*/
delete(key) {
return this.database.delete(key).pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.delete(key)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, undefined); }));
}
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.clear().subscribe(() => {});
*/
clear() {
return this.database.clear().pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.clear()),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => {
for (const key of this.notifiers.keys()) {
this.notify(key, undefined);
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.set('key', 'value').subscribe(() => {});
*/
set(key, data, schema) {
/* Storing `undefined` or `null` is useless and can cause issues in `indexedDb` in some browsers,
* so removing item instead for all storages to have a consistent API */
if ((data === undefined) || (data === null)) {
return this.delete(key);
}
}));
}
/**
* Get all keys stored in storage. Note **this is an *iterating* `Observable`**:
* * if there is no key, the `next` callback will not be invoked,
* * if you need to wait the whole operation to end, be sure to act in the `complete` callback,
* as this `Observable` can emit several values and so will invoke the `next` callback several times.
* @returns A list of the keys wrapped in a RxJS `Observable`
*
* @example
* this.storageMap.keys().subscribe({
* next: (key) => { console.log(key); },
* complete: () => { console.log('Done'); },
* });
*/
keys() {
return this.database.keys()
/* Validate data against a JSON schema if provided */
if (schema && !this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
}
return this.database.set(key, data).pipe(
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.keys()));
}
/**
* Tells if a key exists in storage
* @returns A RxJS `Observable` telling if the key exists
*
* @example
* this.storageMap.has('key').subscribe((hasKey) => {
* if (hasKey) {}
* });
*/
has(key) {
return this.database.has(key)
this.catchIDBBroken(() => this.database.set(key, data)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, data); }));
}
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.delete('key').subscribe(() => {});
*/
delete(key) {
return this.database.delete(key).pipe(
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.has(key)));
}
watch(key, schema) {
/* Check if there is already a notifier and cast according to schema */
let notifier = this.notifiers.get(key);
if (!notifier) {
/* Create a notifier and cast according to schema */
notifier = new ReplaySubject(1);
/* Memorize the notifier */
this.notifiers.set(key, notifier);
/* Get the current item value */
this.get(key, schema).subscribe({
next: (result) => notifier.next(result),
error: (error) => notifier.error(error),
});
this.catchIDBBroken(() => this.database.delete(key)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, undefined); }));
}
/* Only the public API of the `Observable` should be returned */
return notifier.asObservable();
}
/**
* Notify when a value changes
* @param key The item's key
* @param data The new value
*/
notify(key, value) {
const notifier = this.notifiers.get(key);
if (notifier) {
notifier.next(value);
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.clear().subscribe(() => {});
*/
clear() {
return this.database.clear().pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.clear()),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => {
for (const key of this.notifiers.keys()) {
this.notify(key, undefined);
}
}));
}
}
/**
* RxJS operator to catch if `indexedDB` is broken
* @param operationCallback Callback with the operation to redo
*/
catchIDBBroken(operationCallback) {
return catchError((error) => {
/* Check if `indexedDB` is broken based on error message (the specific error class seems to be lost in the process) */
if ((error !== undefined) && (error !== null) && (error.message === IDB_BROKEN_ERROR)) {
/* When storage is fully disabled in browser (via the "Block all cookies" option),
* just trying to check `localStorage` variable causes a security exception.
* Prevents https://github.com/cyrilletuzi/angular-async-local-storage/issues/118
*/
try {
if ('getItem' in localStorage) {
/* Fallback to `localStorage` if available */
this.database = new LocalStorageDatabase(this.LSPrefix);
/**
* Get all keys stored in storage. Note **this is an *iterating* `Observable`**:
* * if there is no key, the `next` callback will not be invoked,
* * if you need to wait the whole operation to end, be sure to act in the `complete` callback,
* as this `Observable` can emit several values and so will invoke the `next` callback several times.
* @returns A list of the keys wrapped in a RxJS `Observable`
*
* @example
* this.storageMap.keys().subscribe({
* next: (key) => { console.log(key); },
* complete: () => { console.log('Done'); },
* });
*/
keys() {
return this.database.keys()
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.keys()));
}
/**
* Tells if a key exists in storage
* @returns A RxJS `Observable` telling if the key exists
*
* @example
* this.storageMap.has('key').subscribe((hasKey) => {
* if (hasKey) {}
* });
*/
has(key) {
return this.database.has(key)
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.has(key)));
}
watch(key, schema) {
/* Check if there is already a notifier and cast according to schema */
let notifier = this.notifiers.get(key);
if (!notifier) {
/* Create a notifier and cast according to schema */
notifier = new ReplaySubject(1);
/* Memorize the notifier */
this.notifiers.set(key, notifier);
/* Get the current item value */
this.get(key, schema).subscribe({
next: (result) => notifier.next(result),
error: (error) => notifier.error(error),
});
}
/* Only the public API of the `Observable` should be returned */
return notifier.asObservable();
}
/**
* Notify when a value changes
* @param key The item's key
* @param data The new value
*/
notify(key, value) {
const notifier = this.notifiers.get(key);
if (notifier) {
notifier.next(value);
}
}
/**
* RxJS operator to catch if `indexedDB` is broken
* @param operationCallback Callback with the operation to redo
*/
catchIDBBroken(operationCallback) {
return catchError((error) => {
/* Check if `indexedDB` is broken based on error message (the specific error class seems to be lost in the process) */
if ((error !== undefined) && (error !== null) && (error.message === IDB_BROKEN_ERROR)) {
/* When storage is fully disabled in browser (via the "Block all cookies" option),
* just trying to check `localStorage` variable causes a security exception.
* Prevents https://github.com/cyrilletuzi/angular-async-local-storage/issues/118
*/
try {
if ('getItem' in localStorage) {
/* Fallback to `localStorage` if available */
this.database = new LocalStorageDatabase(this.LSPrefix);
}
else {
/* Fallback to memory storage otherwise */
this.database = new MemoryDatabase();
}
}
else {
catch (_a) {
/* Fallback to memory storage otherwise */
this.database = new MemoryDatabase();
}
/* Redo the operation */
return operationCallback();
}
catch (_a) {
/* Fallback to memory storage otherwise */
this.database = new MemoryDatabase();
else {
/* Otherwise, rethrow the error */
return throwError(error);
}
/* Redo the operation */
return operationCallback();
}
else {
/* Otherwise, rethrow the error */
return throwError(error);
}
});
}
};
StorageMap.ctorParameters = () => [
{ type: LocalDatabase },
{ type: JSONValidator },
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
StorageMap.ɵprov = i0.ɵɵdefineInjectable({ factory: function StorageMap_Factory() { return new StorageMap(i0.ɵɵinject(i1.LocalDatabase), i0.ɵɵinject(i2.JSONValidator), i0.ɵɵinject(i3.LS_PREFIX)); }, token: StorageMap, providedIn: "root" });
StorageMap = __decorate([
Injectable({
providedIn: 'root'
}),
__param(2, Inject(LS_PREFIX))
], StorageMap);
});
}
};
StorageMap.ctorParameters = () => [
{ type: LocalDatabase },
{ type: JSONValidator },
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
StorageMap.ɵprov = i0.ɵɵdefineInjectable({ factory: function StorageMap_Factory() { return new StorageMap(i0.ɵɵinject(i1.LocalDatabase), i0.ɵɵinject(i2.JSONValidator), i0.ɵɵinject(i3.LS_PREFIX)); }, token: StorageMap, providedIn: "root" });
StorageMap = __decorate([
Injectable({
providedIn: 'root'
}),
__param(2, Inject(LS_PREFIX))
], StorageMap);
return StorageMap;
})();
export { StorageMap };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS1tYXAuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BuZ3gtcHdhL2xvY2FsLXN0b3JhZ2UvIiwic291cmNlcyI6WyJsaWIvc3RvcmFnZXMvc3RvcmFnZS1tYXAuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFjLFVBQVUsRUFBRSxFQUFFLEVBQW9CLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNuRixPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQU0zRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDcEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDMUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7Ozs7O0FBSy9DLElBQWEsVUFBVSxHQUF2QixNQUFhLFVBQVU7SUFJckI7Ozs7O09BS0c7SUFDSCxZQUNZLFFBQXVCLEVBQ3ZCLGdCQUErQixJQUFJLGFBQWEsRUFBRSxFQUMvQixXQUFXLEVBQUU7UUFGaEMsYUFBUSxHQUFSLFFBQVEsQ0FBZTtRQUN2QixrQkFBYSxHQUFiLGFBQWEsQ0FBcUM7UUFDL0IsYUFBUSxHQUFSLFFBQVEsQ0FBSztRQVhsQyxjQUFTLEdBQUcsSUFBSSxHQUFH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V0FBTTtvQkFFTiwwQ0FBMEM7b0JBQzFDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztpQkFFdEM7Z0JBRUQsd0JBQXdCO2dCQUN4QixPQUFPLGlCQUFpQixFQUFFLENBQUM7YUFFNUI7aUJBQU07Z0JBRUwsa0NBQWtDO2dCQUNsQyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUUxQjtRQUVILENBQUMsQ0FBQyxDQUFDO0lBRUwsQ0FBQztDQUVGLENBQUE7O1lBell1QixhQUFhO1lBQ1IsYUFBYTs0Q0FDckMsTUFBTSxTQUFDLFNBQVM7OztBQWJSLFVBQVU7SUFIdEIsVUFBVSxDQUFDO1FBQ1YsVUFBVSxFQUFFLE1BQU07S0FDbkIsQ0FBQztJQWNHLFdBQUEsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0dBYlQsVUFBVSxDQW9adEI7U0FwWlksVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgdGhyb3dFcnJvciwgb2YsIE9wZXJhdG9yRnVuY3Rpb24sIFJlcGxheVN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1lcmdlTWFwLCBjYXRjaEVycm9yLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIEpTT05TY2hlbWEsIEpTT05TY2hlbWFCb29sZWFuLCBKU09OU2NoZW1hSW50ZWdlcixcbiAgSlNPTlNjaGVtYU51bWJlciwgSlNPTlNjaGVtYVN0cmluZywgSlNPTlNjaGVtYUFycmF5T2YsXG59IGZyb20gJy4uL3ZhbGlkYXRpb24vanNvbi1zY2hlbWEnO1xuaW1wb3J0IHsgSlNPTlZhbGlkYXRvciB9IGZyb20gJy4uL3ZhbGlkYXRpb24vanNvbi12YWxpZGF0b3InO1xuaW1wb3J0IHsgSW5kZXhlZERCRGF0YWJhc2UgfSBmcm9tICcuLi9kYXRhYmFzZXMvaW5kZXhlZGRiLWRhdGFiYXNlJztcbmltcG9ydCB7IExvY2FsU3RvcmFnZURhdGFiYXNlIH0gZnJvbSAnLi4vZGF0YWJhc2VzL2xvY2Fsc3RvcmFnZS1kYXRhYmFzZSc7XG5pbXBvcnQgeyBNZW1vcnlEYXRhYmFzZSB9IGZyb20gJy4uL2RhdGFiYXNlcy9tZW1vcnktZGF0YWJhc2UnO1xuaW1wb3J0IHsgTG9jYWxEYXRhYmFzZSB9IGZyb20gJy4uL2RhdGFiYXNlcy9sb2NhbC1kYXRhYmFzZSc7XG5pbXBvcnQgeyBJREJfQlJPS0VOX0VSUk9SIH0gZnJvbSAnLi4vZGF0YWJhc2VzL2V4Y2VwdGlvbnMnO1xuaW1wb3J0IHsgTFNfUFJFRklYIH0gZnJvbSAnLi4vdG9rZW5zJztcbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvciB9IGZyb20gJy4vZXhjZXB0aW9ucyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFN0b3JhZ2VNYXAge1xuXG4gIHByb3RlY3RlZCBub3RpZmllcnMgPSBuZXcgTWFwPHN0cmluZywgUmVwbGF5U3ViamVjdDx1bmtub3duPj4oKTtcblxuICAvKipcbiAgICogQ29uc3RydWN0b3IgcGFyYW1zIGFyZSBwcm92aWRlZCBieSBBbmd1bGFyIChidXQgY2FuIGFsc28gYmUgcGFzc2VkIG1hbnVhbGx5IGluIHRlc3RzKVxuICAgKiBAcGFyYW0gZGF0YWJhc2UgU3RvcmFnZSB0byB1c2VcbiAgICogQHBhcmFtIGpzb25WYWxpZGF0b3IgVmFsaWRhdG9yIHNlcnZpY2VcbiAgICogQHBhcmFtIExTUHJlZml4IFByZWZpeCBmb3IgYGxvY2FsU3RvcmFnZWAga2V5cyB0byBhdm9pZCBjb2xsaXNpb24gZm9yIG11bHRpcGxlIGFwcHMgb24gdGhlIHNhbWUgc3ViZG9tYWluIG9yIGZvciBpbnRlcm9wZXJhYmlsaXR5XG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgZGF0YWJhc2U6IExvY2FsRGF0YWJhc2UsXG4gICAgcHJvdGVjdGVkIGpzb25WYWxpZGF0b3I6IEpTT05WYWxpZGF0b3IgPSBuZXcgSlNPTlZhbGlkYXRvcigpLFxuICAgIEBJbmplY3QoTFNfUFJFRklYKSBwcm90ZWN0ZWQgTFNQcmVmaXggPSAnJyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiAqKk51bWJlciBvZiBpdGVtcyoqIGluIHN0b3JhZ2UsIHdyYXBwZWQgaW4gYW4gYE9ic2VydmFibGVgLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuc2l6ZS5zdWJzY3JpYmUoKHNpemUpID0+IHtcbiAgICogICBjb25zb2xlLmxvZyhzaXplKTtcbiAgICogfSk7XG4gICAqL1xuICBnZXQgc2l6ZSgpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2Uuc2l6ZVxuICAgICAgLyogQ2F0Y2ggaWYgYGluZGV4ZWREYmAgaXMgYnJva2VuICovXG4gICAgICAucGlwZSh0aGlzLmNhdGNoSURCQnJva2VuKCgpID0+IHRoaXMuZGF0YWJhc2Uuc2l6ZSkpO1xuXG4gIH1cblxuICAvKipcbiAgICogVGVsbHMgeW91IHdoaWNoIHN0b3JhZ2UgZW5naW5lIGlzIHVzZWQuICpPbmx5IHVzZWZ1bCBmb3IgaW50ZXJvcGVyYWJpbGl0eS4qXG4gICAqIE5vdGUgdGhhdCBkdWUgdG8gc29tZSBicm93c2VycyBpc3N1ZXMgaW4gc29tZSBzcGVjaWFsIGNvbnRleHRzXG4gICAqIChGaXJlZm94IHByaXZhdGUgbW9kZSBhbmQgU2FmYXJpIGNyb3NzLW9yaWdpbiBpZnJhbWVzKSxcbiAgICogKip0aGlzIGluZm9ybWF0aW9uIG1heSBiZSB3cm9uZyBhdCBpbml0aWFsaXphdGlvbiwqKlxuICAgKiBhcyB0aGUgc3RvcmFnZSBjb3VsZCBmYWxsYmFjayBmcm9tIGBpbmRleGVkREJgIHRvIGBsb2NhbFN0b3JhZ2VgXG4gICAqIG9ubHkgYWZ0ZXIgYSBmaXJzdCByZWFkIG9yIHdyaXRlIG9wZXJhdGlvbi5cbiAgICogQHJldHVybnMgU3RvcmFnZSBlbmdpbmUgdXNlZFxuICAgKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFzdGVyL2RvY3MvSU5URVJPUEVSQUJJTElUWS5tZH1cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaWYgKHRoaXMuc3RvcmFnZU1hcC5iYWNraW5nRW5naW5lID09PSAnaW5kZXhlZERCJykge31cbiAgICovXG4gIGdldCBiYWNraW5nRW5naW5lKCk6ICdpbmRleGVkREInIHwgJ2xvY2FsU3RvcmFnZScgfMKgJ21lbW9yeScgfCAndW5rbm93bicge1xuXG4gICAgaWYgKHRoaXMuZGF0YWJhc2UgaW5zdGFuY2VvZiBJbmRleGVkREJEYXRhYmFzZSkge1xuXG4gICAgICByZXR1cm4gJ2luZGV4ZWREQic7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YWJhc2UgaW5zdGFuY2VvZiBMb2NhbFN0b3JhZ2VEYXRhYmFzZSkge1xuXG4gICAgICByZXR1cm4gJ2xvY2FsU3RvcmFnZSc7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YWJhc2UgaW5zdGFuY2VvZiBNZW1vcnlEYXRhYmFzZSkge1xuXG4gICAgICByZXR1cm4gJ21lbW9yeSc7XG5cbiAgICB9IGVsc2Uge1xuXG4gICAgICByZXR1cm4gJ3Vua25vd24nO1xuXG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogSW5mbyBhYm91dCBgaW5kZXhlZERCYCBkYXRhYmFzZS4gKk9ubHkgdXNlZnVsIGZvciBpbnRlcm9wZXJhYmlsaXR5LipcbiAgICogQHJldHVybnMgYGluZGV4ZWREQmAgZGF0YWJhc2UgbmFtZSwgc3RvcmUgbmFtZSBhbmQgZGF0YWJhc2UgdmVyc2lvbi5cbiAgICogKipWYWx1ZXMgd2lsbCBiZSBlbXB0eSBpZiB0aGUgc3RvcmFnZSBpcyBub3QgYGluZGV4ZWREQmAsKipcbiAgICogKipzbyBpdCBzaG91bGQgYmUgdXNlZCBhZnRlciBhbiBlbmdpbmUgY2hlY2sqKi5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21hc3Rlci9kb2NzL0lOVEVST1BFUkFCSUxJVFkubWR9XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGlmICh0aGlzLnN0b3JhZ2VNYXAuYmFja2luZ0VuZ2luZSA9PT0gJ2luZGV4ZWREQicpIHtcbiAgICogICBjb25zdCB7IGRhdGFiYXNlLCBzdG9yZSwgdmVyc2lvbiB9ID0gdGhpcy5zdG9yYWdlTWFwLmJhY2tpbmdTdG9yZTtcbiAgICogfVxuICAgKi9cbiAgZ2V0IGJhY2tpbmdTdG9yZSgpOiB7IGRhdGFiYXNlOiBzdHJpbmcsIHN0b3JlOiBzdHJpbmcsIHZlcnNpb246IG51bWJlciB9IHtcblxuICAgIHJldHVybiAodGhpcy5kYXRhYmFzZSBpbnN0YW5jZW9mIEluZGV4ZWREQkRhdGFiYXNlKSA/XG4gICAgICB0aGlzLmRhdGFiYXNlLmJhY2tpbmdTdG9yZSA6XG4gICAgICB7IGRhdGFiYXNlOiAnJywgc3RvcmU6ICcnLCB2ZXJzaW9uOiAwIH07XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBJbmZvIGFib3V0IGBsb2NhbFN0b3JhZ2VgIGZhbGxiYWNrIHN0b3JhZ2UuICpPbmx5IHVzZWZ1bCBmb3IgaW50ZXJvcGVyYWJpbGl0eS4qXG4gICAqIEByZXR1cm5zIGBsb2NhbFN0b3JhZ2VgIHByZWZpeC5cbiAgICogKipWYWx1ZXMgd2lsbCBiZSBlbXB0eSBpZiB0aGUgc3RvcmFnZSBpcyBub3QgYGxvY2FsU3RvcmFnZWAsKipcbiAgICogKipzbyBpdCBzaG91bGQgYmUgdXNlZCBhZnRlciBhbiBlbmdpbmUgY2hlY2sqKi5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21hc3Rlci9kb2NzL0lOVEVST1BFUkFCSUxJVFkubWR9XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGlmICh0aGlzLnN0b3JhZ2VNYXAuYmFja2luZ0VuZ2luZSA9PT0gJ2xvY2FsU3RvcmFnZScpIHtcbiAgICogICBjb25zdCB7IHByZWZpeCB9ID0gdGhpcy5zdG9yYWdlTWFwLmZhbGxiYWNrQmFja2luZ1N0b3JlO1xuICAgKiB9XG4gICAqL1xuICBnZXQgZmFsbGJhY2tCYWNraW5nU3RvcmUoKTogeyBwcmVmaXg6IHN0cmluZyB9IHtcblxuICAgIHJldHVybiAodGhpcy5kYXRhYmFzZSBpbnN0YW5jZW9mIExvY2FsU3RvcmFnZURhdGFiYXNlKSA/XG4gICAgICB7IHByZWZpeDogdGhpcy5kYXRhYmFzZS5wcmVmaXggfSA6XG4gICAgICB7IHByZWZpeDogJycgfTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBpdGVtIHZhbHVlIGluIHN0b3JhZ2UuXG4gICAqIFRoZSBzaWduYXR1cmUgaGFzIG1hbnkgb3ZlcmxvYWRzIGR1ZSB0byB2YWxpZGF0aW9uLCAqKnBsZWFzZSByZWZlciB0byB0aGUgZG9jdW1lbnRhdGlvbi4qKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFzdGVyL2RvY3MvVkFMSURBVElPTi5tZH1cbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gc2NoZW1hIE9wdGlvbmFsIEpTT04gc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBkYXRhXG4gICAqIEByZXR1cm5zIFRoZSBpdGVtJ3MgdmFsdWUgaWYgdGhlIGtleSBleGlzdHMsIGB1bmRlZmluZWRgIG90aGVyd2lzZSwgd3JhcHBlZCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMuc3RvcmFnZU1hcC5nZXQoJ2tleScsIHsgdHlwZTogJ3N0cmluZycgfSkuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICogICByZXN1bHQ7IC8vIHN0cmluZyBvciB1bmRlZmluZWRcbiAgICogfSk7XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGludGVyZmFjZSBVc2VyIHtcbiAgICogICBmaXJzdE5hbWU6IHN0cmluZztcbiAgICogICBsYXN0TmFtZT86IHN0cmluZztcbiAgICogfVxuICAgKlxuICAgKiBjb25zdCBzY2hlbWEgPSB7XG4gICAqICAgdHlwZTogJ29iamVjdCcsXG4gICAqICAgcHJvcGVydGllczoge1xuICAgKiAgICAgZmlyc3ROYW1lOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAqICAgICBsYXN0TmFtZTogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgKiAgIH0sXG4gICAqICAgcmVxdWlyZWQ6IFsnZmlyc3ROYW1lJ11cbiAgICogfTtcbiAgICpcbiAgICogdGhpcy5zdG9yYWdlTWFwLmdldDxVc2VyPigndXNlcicsIHNjaGVtYSkuc3Vic2NyaWJlKCh1c2VyKSA9PiB7XG4gICAqICAgaWYgKHVzZXIpIHtcbiAgICogICAgIHVzZXIuZmlyc3ROYW1lO1xuICAgKiAgIH1cbiAgICogfSk7XG4gICAqL1xuICBnZXQ8VCA9IHN0cmluZz4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYVN0cmluZyk6IE9ic2VydmFibGU8c3RyaW5nIHwgdW5kZWZpbmVkPjtcbiAgZ2V0PFQgPSBudW1iZXI+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFJbnRlZ2VywqB8IEpTT05TY2hlbWFOdW1iZXIpOiBPYnNlcnZhYmxlPG51bWJlciB8IHVuZGVmaW5lZD47XG4gIGdldDxUID0gYm9vbGVhbj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUJvb2xlYW4pOiBPYnNlcnZhYmxlPGJvb2xlYW4gfCB1bmRlZmluZWQ+O1xuICBnZXQ8VCA9IHN0cmluZ1tdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hU3RyaW5nPik6IE9ic2VydmFibGU8c3RyaW5nW10gfCB1bmRlZmluZWQ+O1xuICBnZXQ8VCA9IG51bWJlcltdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hSW50ZWdlcsKgfCBKU09OU2NoZW1hTnVtYmVyPik6IE9ic2VydmFibGU8bnVtYmVyW10gfCB1bmRlZmluZWQ+O1xuICBnZXQ8VCA9IGJvb2xlYW5bXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYUJvb2xlYW4+KTogT2JzZXJ2YWJsZTxib29sZWFuW10gfCB1bmRlZmluZWQ+O1xuICBnZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xuICBnZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBzY2hlbWE/OiBKU09OU2NoZW1hKTogT2JzZXJ2YWJsZTx1bmtub3duPjtcbiAgZ2V0PFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8dW5rbm93bj4ge1xuXG4gICAgLyogR2V0IHRoZSBkYXRhIGluIHN0b3JhZ2UgKi9cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5nZXQ8VD4oa2V5KS5waXBlKFxuICAgICAgLyogQ2hlY2sgaWYgYGluZGV4ZWREYmAgaXMgYnJva2VuICovXG4gICAgICB0aGlzLmNhdGNoSURCQnJva2VuKCgpID0+IHRoaXMuZGF0YWJhc2UuZ2V0PFQ+KGtleSkpLFxuICAgICAgbWVyZ2VNYXAoKGRhdGEpID0+IHtcblxuICAgICAgICAvKiBObyBuZWVkIHRvIHZhbGlkYXRlIGlmIHRoZSBkYXRhIGlzIGVtcHR5ICovXG4gICAgICAgIGlmICgoZGF0YSA9PT0gdW5kZWZpbmVkKSB8fCAoZGF0YSA9PT0gbnVsbCkpIHtcblxuICAgICAgICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoc2NoZW1hKSB7XG5cbiAgICAgICAgICAvKiBWYWxpZGF0ZSBkYXRhIGFnYWluc3QgYSBKU09OIHNjaGVtYSBpZiBwcm92aWRlZCAqL1xuICAgICAgICAgIGlmICghdGhpcy5qc29uVmFsaWRhdG9yLnZhbGlkYXRlKGRhdGEsIHNjaGVtYSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKG5ldyBWYWxpZGF0aW9uRXJyb3IoKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyogRGF0YSBoYXZlIGJlZW4gY2hlY2tlZCwgc28gaXQncyBPSyB0byBjYXN0ICovXG4gICAgICAgICAgcmV0dXJuIG9mKGRhdGEgYXMgVCB8IHVuZGVmaW5lZCk7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIC8qIENhc3QgdG8gdW5rbm93biBhcyB0aGUgZGF0YSB3YXNuJ3QgY2hlY2tlZCAqL1xuICAgICAgICByZXR1cm4gb2YoZGF0YSBhcyB1bmtub3duKTtcblxuICAgICAgfSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFNldCBhbiBpdGVtIGluIHN0b3JhZ2UuXG4gICAqIE5vdGUgdGhhdCBzZXR0aW5nIGBudWxsYCBvciBgdW5kZWZpbmVkYCB3aWxsIHJlbW92ZSB0aGUgaXRlbSB0byBhdm9pZCBzb21lIGJyb3dzZXJzIGlzc3Vlcy5cbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gZGF0YSBUaGUgaXRlbSdzIHZhbHVlXG4gICAqIEBwYXJhbSBzY2hlbWEgT3B0aW9uYWwgSlNPTiBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIGRhdGFcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuc2V0KCdrZXknLCAndmFsdWUnKS5zdWJzY3JpYmUoKCkgPT4ge30pO1xuICAgKi9cbiAgc2V0KGtleTogc3RyaW5nLCBkYXRhOiB1bmtub3duLCBzY2hlbWE/OiBKU09OU2NoZW1hKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIC8qIFN0b3JpbmcgYHVuZGVmaW5lZGAgb3IgYG51bGxgIGlzIHVzZWxlc3MgYW5kIGNhbiBjYXVzZSBpc3N1ZXMgaW4gYGluZGV4ZWREYmAgaW4gc29tZSBicm93c2VycyxcbiAgICAgKiBzbyByZW1vdmluZyBpdGVtIGluc3RlYWQgZm9yIGFsbCBzdG9yYWdlcyB0byBoYXZlIGEgY29uc2lzdGVudCBBUEkgKi9cbiAgICBpZiAoKGRhdGEgPT09IHVuZGVmaW5lZCkgfHwgKGRhdGEgPT09IG51bGwpKSB7XG4gICAgICByZXR1cm4gdGhpcy5kZWxldGUoa2V5KTtcbiAgICB9XG5cbiAgICAvKiBWYWxpZGF0ZSBkYXRhIGFnYWluc3QgYSBKU09OIHNjaGVtYSBpZiBwcm92aWRlZCAqL1xuICAgIGlmIChzY2hlbWEgJiYgIXRoaXMuanNvblZhbGlkYXRvci52YWxpZGF0ZShkYXRhLCBzY2hlbWEpKSB7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcihuZXcgVmFsaWRhdGlvbkVycm9yKCkpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlLnNldChrZXksIGRhdGEpLnBpcGUoXG4gICAgICAvKiBDYXRjaCBpZiBgaW5kZXhlZERiYCBpcyBicm9rZW4gKi9cbiAgICAgIHRoaXMuY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5zZXQoa2V5LCBkYXRhKSksXG4gICAgICAvKiBOb3RpZnkgd2F0Y2hlcnMgKG11c3QgYmUgbGFzdCBiZWNhdXNlIGl0IHNob3VsZCBvbmx5IGhhcHBlbiBpZiB0aGUgb3BlcmF0aW9uIHN1Y2NlZWRzKSAqL1xuICAgICAgdGFwKCgpID0+IHsgdGhpcy5ub3RpZnkoa2V5LCBkYXRhKTsgfSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYW4gaXRlbSBpbiBzdG9yYWdlXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuZGVsZXRlKCdrZXknKS5zdWJzY3JpYmUoKCkgPT4ge30pO1xuICAgKi9cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlLmRlbGV0ZShrZXkpLnBpcGUoXG4gICAgICAvKiBDYXRjaCBpZiBgaW5kZXhlZERiYCBpcyBicm9rZW4gKi9cbiAgICAgIHRoaXMuY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5kZWxldGUoa2V5KSksXG4gICAgICAvKiBOb3RpZnkgd2F0Y2hlcnMgKG11c3QgYmUgbGFzdCBiZWNhdXNlIGl0IHNob3VsZCBvbmx5IGhhcHBlbiBpZiB0aGUgb3BlcmF0aW9uIHN1Y2NlZWRzKSAqL1xuICAgICAgdGFwKCgpID0+IHsgdGhpcy5ub3RpZnkoa2V5LCB1bmRlZmluZWQpOyB9KSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGFsbCBpdGVtcyBpbiBzdG9yYWdlXG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLmNsZWFyKCkuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIGNsZWFyKCk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5jbGVhcigpLnBpcGUoXG4gICAgICAvKiBDYXRjaCBpZiBgaW5kZXhlZERiYCBpcyBicm9rZW4gKi9cbiAgICAgIHRoaXMuY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5jbGVhcigpKSxcbiAgICAgIC8qIE5vdGlmeSB3YXRjaGVycyAobXVzdCBiZSBsYXN0IGJlY2F1c2UgaXQgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHRoZSBvcGVyYXRpb24gc3VjY2VlZHMpICovXG4gICAgICB0YXAoKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB0aGlzLm5vdGlmaWVycy5rZXlzKCkpIHtcbiAgICAgICAgICB0aGlzLm5vdGlmeShrZXksIHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGtleXMgc3RvcmVkIGluIHN0b3JhZ2UuIE5vdGUgKip0aGlzIGlzIGFuICppdGVyYXRpbmcqIGBPYnNlcnZhYmxlYCoqOlxuICAgKiAqIGlmIHRoZXJlIGlzIG5vIGtleSwgdGhlIGBuZXh0YCBjYWxsYmFjayB3aWxsIG5vdCBiZSBpbnZva2VkLFxuICAgKiAqIGlmIHlvdSBuZWVkIHRvIHdhaXQgdGhlIHdob2xlIG9wZXJhdGlvbiB0byBlbmQsIGJlIHN1cmUgdG8gYWN0IGluIHRoZSBgY29tcGxldGVgIGNhbGxiYWNrLFxuICAgKiBhcyB0aGlzIGBPYnNlcnZhYmxlYCBjYW4gZW1pdCBzZXZlcmFsIHZhbHVlcyBhbmQgc28gd2lsbCBpbnZva2UgdGhlIGBuZXh0YCBjYWxsYmFjayBzZXZlcmFsIHRpbWVzLlxuICAgKiBAcmV0dXJucyBBIGxpc3Qgb2YgdGhlIGtleXMgd3JhcHBlZCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMuc3RvcmFnZU1hcC5rZXlzKCkuc3Vic2NyaWJlKHtcbiAgICogICBuZXh0OiAoa2V5KSA9PiB7IGNvbnNvbGUubG9nKGtleSk7IH0sXG4gICAqICAgY29tcGxldGU6ICgpID0+IHsgY29uc29sZS5sb2coJ0RvbmUnKTsgfSxcbiAgICogfSk7XG4gICAqL1xuICBrZXlzKCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG5cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5rZXlzKClcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgLnBpcGUodGhpcy5jYXRjaElEQkJyb2tlbigoKSA9PiB0aGlzLmRhdGFiYXNlLmtleXMoKSkpO1xuXG4gIH1cblxuICAvKipcbiAgICogVGVsbHMgaWYgYSBrZXkgZXhpc3RzIGluIHN0b3JhZ2VcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0ZWxsaW5nIGlmIHRoZSBrZXkgZXhpc3RzXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMuc3RvcmFnZU1hcC5oYXMoJ2tleScpLnN1YnNjcmliZSgoaGFzS2V5KSA9PiB7XG4gICAqICAgaWYgKGhhc0tleSkge31cbiAgICogfSk7XG4gICAqL1xuICBoYXMoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcblxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlLmhhcyhrZXkpXG4gICAgICAvKiBDYXRjaCBpZiBgaW5kZXhlZERiYCBpcyBicm9rZW4gKi9cbiAgICAgIC5waXBlKHRoaXMuY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5oYXMoa2V5KSkpO1xuXG4gIH1cblxuICAvKipcbiAgICogV2F0Y2ggYW4gaXRlbSB2YWx1ZSBpbiBzdG9yYWdlLlxuICAgKiAqKk5vdGUgb25seSBjaGFuZ2VzIGRvbmUgdmlhIHRoaXMgbGliIHdpbGwgYmUgd2F0Y2hlZCoqLCBleHRlcm5hbCBjaGFuZ2VzIGluIHN0b3JhZ2UgY2FuJ3QgYmUgZGV0ZWN0ZWQuXG4gICAqIFRoZSBzaWduYXR1cmUgaGFzIG1hbnkgb3ZlcmxvYWRzIGR1ZSB0byB2YWxpZGF0aW9uLCAqKnBsZWFzZSByZWZlciB0byB0aGUgZG9jdW1lbnRhdGlvbi4qKlxuICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvYmxvYi9tYXN0ZXIvZG9jcy9WQUxJREFUSU9OLm1kXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXkgdG8gd2F0Y2hcbiAgICogQHBhcmFtIHNjaGVtYSBPcHRpb25hbCBKU09OIHNjaGVtYSB0byB2YWxpZGF0ZSB0aGUgaW5pdGlhbCB2YWx1ZVxuICAgKiBAcmV0dXJucyBBbiBpbmZpbml0ZSBgT2JzZXJ2YWJsZWAgZ2l2aW5nIHRoZSBjdXJyZW50IHZhbHVlXG4gICAqL1xuICB3YXRjaDxUID0gc3RyaW5nPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hU3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICB3YXRjaDxUID0gbnVtYmVyPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hSW50ZWdlciB8IEpTT05TY2hlbWFOdW1iZXIpOiBPYnNlcnZhYmxlPG51bWJlciB8IHVuZGVmaW5lZD47XG4gIHdhdGNoPFQgPSBib29sZWFuPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQm9vbGVhbik6IE9ic2VydmFibGU8Ym9vbGVhbiB8IHVuZGVmaW5lZD47XG4gIHdhdGNoPFQgPSBzdHJpbmdbXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYVN0cmluZz4pOiBPYnNlcnZhYmxlPHN0cmluZ1tdIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCA9IG51bWJlcltdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hSW50ZWdlciB8IEpTT05TY2hlbWFOdW1iZXI+KTogT2JzZXJ2YWJsZTxudW1iZXJbXSB8IHVuZGVmaW5lZD47XG4gIHdhdGNoPFQgPSBib29sZWFuW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFCb29sZWFuPik6IE9ic2VydmFibGU8Ym9vbGVhbltdIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xuICB3YXRjaDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHNjaGVtYT86IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPHVua25vd24+O1xuICB3YXRjaDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHNjaGVtYT86IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPHVua25vd24+IHtcblxuICAgIC8qIENoZWNrIGlmIHRoZXJlIGlzIGFscmVhZHkgYSBub3RpZmllciBhbmQgY2FzdCBhY2NvcmRpbmcgdG8gc2NoZW1hICovXG4gICAgbGV0IG5vdGlmaWVyID0gdGhpcy5ub3RpZmllcnMuZ2V0KGtleSkgYXMgUmVwbGF5U3ViamVjdDx0eXBlb2Ygc2NoZW1hIGV4dGVuZHMgSlNPTlNjaGVtYSA/IChUIHwgdW5kZWZpbmVkKSA6IHVua25vd24+O1xuXG4gICAgaWYgKCFub3RpZmllcikge1xuXG4gICAgICAvKiBDcmVhdGUgYSBub3RpZmllciBhbmQgY2FzdCBhY2NvcmRpbmcgdG8gc2NoZW1hICovXG4gICAgICBub3RpZmllciA9IG5ldyBSZXBsYXlTdWJqZWN0PHR5cGVvZiBzY2hlbWEgZXh0ZW5kcyBKU09OU2NoZW1hID8gKFQgfCB1bmRlZmluZWQpIDogdW5rbm93bj4oMSk7XG5cbiAgICAgIC8qIE1lbW9yaXplIHRoZSBub3RpZmllciAqL1xuICAgICAgdGhpcy5ub3RpZmllcnMuc2V0KGtleSwgbm90aWZpZXIpO1xuXG4gICAgICAvKiBHZXQgdGhlIGN1cnJlbnQgaXRlbSB2YWx1ZSAqL1xuICAgICAgdGhpcy5nZXQ8VD4oa2V5LCBzY2hlbWEpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXN1bHQpID0+IG5vdGlmaWVyLm5leHQocmVzdWx0KSxcbiAgICAgICAgZXJyb3I6IChlcnJvcikgPT4gbm90aWZpZXIuZXJyb3IoZXJyb3IpLFxuICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICAvKiBPbmx5IHRoZSBwdWJsaWMgQVBJIG9mIHRoZSBgT2JzZXJ2YWJsZWAgc2hvdWxkIGJlIHJldHVybmVkICovXG4gICAgcmV0dXJuIG5vdGlmaWVyLmFzT2JzZXJ2YWJsZSgpO1xuXG4gIH1cblxuICAvKipcbiAgICogTm90aWZ5IHdoZW4gYSB2YWx1ZSBjaGFuZ2VzXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHBhcmFtIGRhdGEgVGhlIG5ldyB2YWx1ZVxuICAgKi9cbiAgcHJvdGVjdGVkIG5vdGlmeShrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiB2b2lkIHtcblxuICAgIGNvbnN0IG5vdGlmaWVyID0gdGhpcy5ub3RpZmllcnMuZ2V0KGtleSk7XG5cbiAgICBpZiAobm90aWZpZXIpIHtcbiAgICAgIG5vdGlmaWVyLm5leHQodmFsdWUpO1xuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIFJ4SlMgb3BlcmF0b3IgdG8gY2F0Y2ggaWYgYGluZGV4ZWREQmAgaXMgYnJva2VuXG4gICAqIEBwYXJhbSBvcGVyYXRpb25DYWxsYmFjayBDYWxsYmFjayB3aXRoIHRoZSBvcGVyYXRpb24gdG8gcmVkb1xuICAgKi9cbiAgcHJvdGVjdGVkIGNhdGNoSURCQnJva2VuPFQ+KG9wZXJhdGlvbkNhbGxiYWNrOiAoKSA9PiBPYnNlcnZhYmxlPFQ+KTogT3BlcmF0b3JGdW5jdGlvbjxULCBUPiB7XG5cbiAgICByZXR1cm4gY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcblxuICAgICAgLyogQ2hlY2sgaWYgYGluZGV4ZWREQmAgaXMgYnJva2VuIGJhc2VkIG9uIGVycm9yIG1lc3NhZ2UgKHRoZSBzcGVjaWZpYyBlcnJvciBjbGFzcyBzZWVtcyB0byBiZSBsb3N0IGluIHRoZSBwcm9jZXNzKSAqL1xuICAgICAgaWYgKChlcnJvciAhPT0gdW5kZWZpbmVkKSAmJiAoZXJyb3IgIT09IG51bGwpICYmIChlcnJvci5tZXNzYWdlID09PSBJREJfQlJPS0VOX0VSUk9SKSkge1xuXG4gICAgICAgIC8qIFdoZW4gc3RvcmFnZSBpcyBmdWxseSBkaXNhYmxlZCBpbiBicm93c2VyICh2aWEgdGhlIFwiQmxvY2sgYWxsIGNvb2tpZXNcIiBvcHRpb24pLFxuICAgICAgICAgKiBqdXN0IHRyeWluZyB0byBjaGVjayBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSBjYXVzZXMgYSBzZWN1cml0eSBleGNlcHRpb24uXG4gICAgICAgICAqIFByZXZlbnRzIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvaXNzdWVzLzExOFxuICAgICAgICAgKi9cbiAgICAgICAgdHJ5IHtcblxuICAgICAgICAgIGlmICgnZ2V0SXRlbScgaW4gbG9jYWxTdG9yYWdlKSB7XG5cbiAgICAgICAgICAgIC8qIEZhbGxiYWNrIHRvIGBsb2NhbFN0b3JhZ2VgIGlmIGF2YWlsYWJsZSAqL1xuICAgICAgICAgICAgdGhpcy5kYXRhYmFzZSA9IG5ldyBMb2NhbFN0b3JhZ2VEYXRhYmFzZSh0aGlzLkxTUHJlZml4KTtcblxuICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIC8qIEZhbGxiYWNrIHRvIG1lbW9yeSBzdG9yYWdlIG90aGVyd2lzZSAqL1xuICAgICAgICAgICAgdGhpcy5kYXRhYmFzZSA9IG5ldyBNZW1vcnlEYXRhYmFzZSgpO1xuXG4gICAgICAgICAgfVxuXG4gICAgICAgIH0gY2F0Y2gge1xuXG4gICAgICAgICAgLyogRmFsbGJhY2sgdG8gbWVtb3J5IHN0b3JhZ2Ugb3RoZXJ3aXNlICovXG4gICAgICAgICAgdGhpcy5kYXRhYmFzZSA9IG5ldyBNZW1vcnlEYXRhYmFzZSgpO1xuXG4gICAgICAgIH1cblxuICAgICAgICAvKiBSZWRvIHRoZSBvcGVyYXRpb24gKi9cbiAgICAgICAgcmV0dXJuIG9wZXJhdGlvbkNhbGxiYWNrKCk7XG5cbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLyogT3RoZXJ3aXNlLCByZXRocm93IHRoZSBlcnJvciAqL1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvcik7XG5cbiAgICAgIH1cblxuICAgIH0pO1xuXG4gIH1cblxufVxuIl19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS1tYXAuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BuZ3gtcHdhL2xvY2FsLXN0b3JhZ2UvIiwic291cmNlcyI6WyJsaWIvc3RvcmFnZXMvc3RvcmFnZS1tYXAuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFjLFVBQVUsRUFBRSxFQUFFLEVBQW9CLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNuRixPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQU0zRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDcEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDMUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7Ozs7O0FBSy9DO0lBQUEsSUFBYSxVQUFVLEdBQXZCLE1BQWEsVUFBVTtRQUlyQjs7Ozs7V0FLRztRQUNILFlBQ1ksUUFBdUIsRUFDdkIsZ0JBQStCLElBQUksYUFBYSxFQUFFLEVBQy9CLFdBQVcsRUFBRTtZQUZoQyxhQUFRLEdBQVIsUUFBUSxDQUFlO1lBQ3ZCLGtCQUFhLEdBQWIsYUFBYSxDQUFxQztZQUMvQixhQUFRLEdBQVIsUUFBUSxDQUFLO1lBWGxDLGNBQVMsR0FBRyxJQUFJ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QUcsSUFBSSxjQUFjLEVBQUUsQ0FBQzt5QkFFdEM7cUJBRUY7b0JBQUMsV0FBTTt3QkFFTiwwQ0FBMEM7d0JBQzFDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztxQkFFdEM7b0JBRUQsd0JBQXdCO29CQUN4QixPQUFPLGlCQUFpQixFQUFFLENBQUM7aUJBRTVCO3FCQUFNO29CQUVMLGtDQUFrQztvQkFDbEMsT0FBTyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBRTFCO1lBRUgsQ0FBQyxDQUFDLENBQUM7UUFFTCxDQUFDO0tBRUYsQ0FBQTs7Z0JBell1QixhQUFhO2dCQUNSLGFBQWE7Z0RBQ3JDLE1BQU0sU0FBQyxTQUFTOzs7SUFiUixVQUFVO1FBSHRCLFVBQVUsQ0FBQztZQUNWLFVBQVUsRUFBRSxNQUFNO1NBQ25CLENBQUM7UUFjRyxXQUFBLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtPQWJULFVBQVUsQ0FvWnRCO3FCQXhhRDtLQXdhQztTQXBaWSxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCB0aHJvd0Vycm9yLCBvZiwgT3BlcmF0b3JGdW5jdGlvbiwgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWVyZ2VNYXAsIGNhdGNoRXJyb3IsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgSlNPTlNjaGVtYSwgSlNPTlNjaGVtYUJvb2xlYW4sIEpTT05TY2hlbWFJbnRlZ2VyLFxuICBKU09OU2NoZW1hTnVtYmVyLCBKU09OU2NoZW1hU3RyaW5nLCBKU09OU2NoZW1hQXJyYXlPZixcbn0gZnJvbSAnLi4vdmFsaWRhdGlvbi9qc29uLXNjaGVtYSc7XG5pbXBvcnQgeyBKU09OVmFsaWRhdG9yIH0gZnJvbSAnLi4vdmFsaWRhdGlvbi9qc29uLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBJbmRleGVkREJEYXRhYmFzZSB9IGZyb20gJy4uL2RhdGFiYXNlcy9pbmRleGVkZGItZGF0YWJhc2UnO1xuaW1wb3J0IHsgTG9jYWxTdG9yYWdlRGF0YWJhc2UgfSBmcm9tICcuLi9kYXRhYmFzZXMvbG9jYWxzdG9yYWdlLWRhdGFiYXNlJztcbmltcG9ydCB7IE1lbW9yeURhdGFiYXNlIH0gZnJvbSAnLi4vZGF0YWJhc2VzL21lbW9yeS1kYXRhYmFzZSc7XG5pbXBvcnQgeyBMb2NhbERhdGFiYXNlIH0gZnJvbSAnLi4vZGF0YWJhc2VzL2xvY2FsLWRhdGFiYXNlJztcbmltcG9ydCB7IElEQl9CUk9LRU5fRVJST1IgfSBmcm9tICcuLi9kYXRhYmFzZXMvZXhjZXB0aW9ucyc7XG5pbXBvcnQgeyBMU19QUkVGSVggfSBmcm9tICcuLi90b2tlbnMnO1xuaW1wb3J0IHsgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi9leGNlcHRpb25zJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgU3RvcmFnZU1hcCB7XG5cbiAgcHJvdGVjdGVkIG5vdGlmaWVycyA9IG5ldyBNYXA8c3RyaW5nLCBSZXBsYXlTdWJqZWN0PHVua25vd24+PigpO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvciBwYXJhbXMgYXJlIHByb3ZpZGVkIGJ5IEFuZ3VsYXIgKGJ1dCBjYW4gYWxzbyBiZSBwYXNzZWQgbWFudWFsbHkgaW4gdGVzdHMpXG4gICAqIEBwYXJhbSBkYXRhYmFzZSBTdG9yYWdlIHRvIHVzZVxuICAgKiBAcGFyYW0ganNvblZhbGlkYXRvciBWYWxpZGF0b3Igc2VydmljZVxuICAgKiBAcGFyYW0gTFNQcmVmaXggUHJlZml4IGZvciBgbG9jYWxTdG9yYWdlYCBrZXlzIHRvIGF2b2lkIGNvbGxpc2lvbiBmb3IgbXVsdGlwbGUgYXBwcyBvbiB0aGUgc2FtZSBzdWJkb21haW4gb3IgZm9yIGludGVyb3BlcmFiaWxpdHlcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBkYXRhYmFzZTogTG9jYWxEYXRhYmFzZSxcbiAgICBwcm90ZWN0ZWQganNvblZhbGlkYXRvcjogSlNPTlZhbGlkYXRvciA9IG5ldyBKU09OVmFsaWRhdG9yKCksXG4gICAgQEluamVjdChMU19QUkVGSVgpIHByb3RlY3RlZCBMU1ByZWZpeCA9ICcnLFxuICApIHt9XG5cbiAgLyoqXG4gICAqICoqTnVtYmVyIG9mIGl0ZW1zKiogaW4gc3RvcmFnZSwgd3JhcHBlZCBpbiBhbiBgT2JzZXJ2YWJsZWAuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMuc3RvcmFnZU1hcC5zaXplLnN1YnNjcmliZSgoc2l6ZSkgPT4ge1xuICAgKiAgIGNvbnNvbGUubG9nKHNpemUpO1xuICAgKiB9KTtcbiAgICovXG4gIGdldCBzaXplKCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG5cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5zaXplXG4gICAgICAvKiBDYXRjaCBpZiBgaW5kZXhlZERiYCBpcyBicm9rZW4gKi9cbiAgICAgIC5waXBlKHRoaXMuY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5zaXplKSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBUZWxscyB5b3Ugd2hpY2ggc3RvcmFnZSBlbmdpbmUgaXMgdXNlZC4gKk9ubHkgdXNlZnVsIGZvciBpbnRlcm9wZXJhYmlsaXR5LipcbiAgICogTm90ZSB0aGF0IGR1ZSB0byBzb21lIGJyb3dzZXJzIGlzc3VlcyBpbiBzb21lIHNwZWNpYWwgY29udGV4dHNcbiAgICogKEZpcmVmb3ggcHJpdmF0ZSBtb2RlIGFuZCBTYWZhcmkgY3Jvc3Mtb3JpZ2luIGlmcmFtZXMpLFxuICAgKiAqKnRoaXMgaW5mb3JtYXRpb24gbWF5IGJlIHdyb25nIGF0IGluaXRpYWxpemF0aW9uLCoqXG4gICAqIGFzIHRoZSBzdG9yYWdlIGNvdWxkIGZhbGxiYWNrIGZyb20gYGluZGV4ZWREQmAgdG8gYGxvY2FsU3RvcmFnZWBcbiAgICogb25seSBhZnRlciBhIGZpcnN0IHJlYWQgb3Igd3JpdGUgb3BlcmF0aW9uLlxuICAgKiBAcmV0dXJucyBTdG9yYWdlIGVuZ2luZSB1c2VkXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvYmxvYi9tYXN0ZXIvZG9jcy9JTlRFUk9QRVJBQklMSVRZLm1kfVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBpZiAodGhpcy5zdG9yYWdlTWFwLmJhY2tpbmdFbmdpbmUgPT09ICdpbmRleGVkREInKSB7fVxuICAgKi9cbiAgZ2V0IGJhY2tpbmdFbmdpbmUoKTogJ2luZGV4ZWREQicgfCAnbG9jYWxTdG9yYWdlJyB8wqAnbWVtb3J5JyB8ICd1bmtub3duJyB7XG5cbiAgICBpZiAodGhpcy5kYXRhYmFzZSBpbnN0YW5jZW9mIEluZGV4ZWREQkRhdGFiYXNlKSB7XG5cbiAgICAgIHJldHVybiAnaW5kZXhlZERCJztcblxuICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhYmFzZSBpbnN0YW5jZW9mIExvY2FsU3RvcmFnZURhdGFiYXNlKSB7XG5cbiAgICAgIHJldHVybiAnbG9jYWxTdG9yYWdlJztcblxuICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhYmFzZSBpbnN0YW5jZW9mIE1lbW9yeURhdGFiYXNlKSB7XG5cbiAgICAgIHJldHVybiAnbWVtb3J5JztcblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIHJldHVybiAndW5rbm93bic7XG5cbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBJbmZvIGFib3V0IGBpbmRleGVkREJgIGRhdGFiYXNlLiAqT25seSB1c2VmdWwgZm9yIGludGVyb3BlcmFiaWxpdHkuKlxuICAgKiBAcmV0dXJucyBgaW5kZXhlZERCYCBkYXRhYmFzZSBuYW1lLCBzdG9yZSBuYW1lIGFuZCBkYXRhYmFzZSB2ZXJzaW9uLlxuICAgKiAqKlZhbHVlcyB3aWxsIGJlIGVtcHR5IGlmIHRoZSBzdG9yYWdlIGlzIG5vdCBgaW5kZXhlZERCYCwqKlxuICAgKiAqKnNvIGl0IHNob3VsZCBiZSB1c2VkIGFmdGVyIGFuIGVuZ2luZSBjaGVjayoqLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFzdGVyL2RvY3MvSU5URVJPUEVSQUJJTElUWS5tZH1cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaWYgKHRoaXMuc3RvcmFnZU1hcC5iYWNraW5nRW5naW5lID09PSAnaW5kZXhlZERCJykge1xuICAgKiAgIGNvbnN0IHsgZGF0YWJhc2UsIHN0b3JlLCB2ZXJzaW9uIH0gPSB0aGlzLnN0b3JhZ2VNYXAuYmFja2luZ1N0b3JlO1xuICAgKiB9XG4gICAqL1xuICBnZXQgYmFja2luZ1N0b3JlKCk6IHsgZGF0YWJhc2U6IHN0cmluZywgc3RvcmU6IHN0cmluZywgdmVyc2lvbjogbnVtYmVyIH0ge1xuXG4gICAgcmV0dXJuICh0aGlzLmRhdGFiYXNlIGluc3RhbmNlb2YgSW5kZXhlZERCRGF0YWJhc2UpID9cbiAgICAgIHRoaXMuZGF0YWJhc2UuYmFja2luZ1N0b3JlIDpcbiAgICAgIHsgZGF0YWJhc2U6ICcnLCBzdG9yZTogJycsIHZlcnNpb246IDAgfTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEluZm8gYWJvdXQgYGxvY2FsU3RvcmFnZWAgZmFsbGJhY2sgc3RvcmFnZS4gKk9ubHkgdXNlZnVsIGZvciBpbnRlcm9wZXJhYmlsaXR5LipcbiAgICogQHJldHVybnMgYGxvY2FsU3RvcmFnZWAgcHJlZml4LlxuICAgKiAqKlZhbHVlcyB3aWxsIGJlIGVtcHR5IGlmIHRoZSBzdG9yYWdlIGlzIG5vdCBgbG9jYWxTdG9yYWdlYCwqKlxuICAgKiAqKnNvIGl0IHNob3VsZCBiZSB1c2VkIGFmdGVyIGFuIGVuZ2luZSBjaGVjayoqLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFzdGVyL2RvY3MvSU5URVJPUEVSQUJJTElUWS5tZH1cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaWYgKHRoaXMuc3RvcmFnZU1hcC5iYWNraW5nRW5naW5lID09PSAnbG9jYWxTdG9yYWdlJykge1xuICAgKiAgIGNvbnN0IHsgcHJlZml4IH0gPSB0aGlzLnN0b3JhZ2VNYXAuZmFsbGJhY2tCYWNraW5nU3RvcmU7XG4gICAqIH1cbiAgICovXG4gIGdldCBmYWxsYmFja0JhY2tpbmdTdG9yZSgpOiB7IHByZWZpeDogc3RyaW5nIH0ge1xuXG4gICAgcmV0dXJuICh0aGlzLmRhdGFiYXNlIGluc3RhbmNlb2YgTG9jYWxTdG9yYWdlRGF0YWJhc2UpID9cbiAgICAgIHsgcHJlZml4OiB0aGlzLmRhdGFiYXNlLnByZWZpeCB9IDpcbiAgICAgIHsgcHJlZml4OiAnJyB9O1xuXG4gIH1cblxuICAvKipcbiAgICogR2V0IGFuIGl0ZW0gdmFsdWUgaW4gc3RvcmFnZS5cbiAgICogVGhlIHNpZ25hdHVyZSBoYXMgbWFueSBvdmVybG9hZHMgZHVlIHRvIHZhbGlkYXRpb24sICoqcGxlYXNlIHJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uLioqXG4gICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvYmxvYi9tYXN0ZXIvZG9jcy9WQUxJREFUSU9OLm1kfVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBzY2hlbWEgT3B0aW9uYWwgSlNPTiBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIGRhdGFcbiAgICogQHJldHVybnMgVGhlIGl0ZW0ncyB2YWx1ZSBpZiB0aGUga2V5IGV4aXN0cywgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLCB3cmFwcGVkIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLmdldCgna2V5JywgeyB0eXBlOiAnc3RyaW5nJyB9KS5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgKiAgIHJlc3VsdDsgLy8gc3RyaW5nIG9yIHVuZGVmaW5lZFxuICAgKiB9KTtcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaW50ZXJmYWNlIFVzZXIge1xuICAgKiAgIGZpcnN0TmFtZTogc3RyaW5nO1xuICAgKiAgIGxhc3ROYW1lPzogc3RyaW5nO1xuICAgKiB9XG4gICAqXG4gICAqIGNvbnN0IHNjaGVtYSA9IHtcbiAgICogICB0eXBlOiAnb2JqZWN0JyxcbiAgICogICBwcm9wZXJ0aWVzOiB7XG4gICAqICAgICBmaXJzdE5hbWU6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICogICAgIGxhc3ROYW1lOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAqICAgfSxcbiAgICogICByZXF1aXJlZDogWydmaXJzdE5hbWUnXVxuICAgKiB9O1xuICAgKlxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuZ2V0PFVzZXI+KCd1c2VyJywgc2NoZW1hKS5zdWJzY3JpYmUoKHVzZXIpID0+IHtcbiAgICogICBpZiAodXNlcikge1xuICAgKiAgICAgdXNlci5maXJzdE5hbWU7XG4gICAqICAgfVxuICAgKiB9KTtcbiAgICovXG4gIGdldDxUID0gc3RyaW5nPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hU3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBnZXQ8VCA9IG51bWJlcj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUludGVnZXLCoHwgSlNPTlNjaGVtYU51bWJlcik6IE9ic2VydmFibGU8bnVtYmVyIHwgdW5kZWZpbmVkPjtcbiAgZ2V0PFQgPSBib29sZWFuPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQm9vbGVhbik6IE9ic2VydmFibGU8Ym9vbGVhbiB8IHVuZGVmaW5lZD47XG4gIGdldDxUID0gc3RyaW5nW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFTdHJpbmc+KTogT2JzZXJ2YWJsZTxzdHJpbmdbXSB8IHVuZGVmaW5lZD47XG4gIGdldDxUID0gbnVtYmVyW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFJbnRlZ2VywqB8IEpTT05TY2hlbWFOdW1iZXI+KTogT2JzZXJ2YWJsZTxudW1iZXJbXSB8IHVuZGVmaW5lZD47XG4gIGdldDxUID0gYm9vbGVhbltdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hQm9vbGVhbj4pOiBPYnNlcnZhYmxlPGJvb2xlYW5bXSB8IHVuZGVmaW5lZD47XG4gIGdldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIGdldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHNjaGVtYT86IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPHVua25vd24+O1xuICBnZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBzY2hlbWE/OiBKU09OU2NoZW1hKTogT2JzZXJ2YWJsZTx1bmtub3duPiB7XG5cbiAgICAvKiBHZXQgdGhlIGRhdGEgaW4gc3RvcmFnZSAqL1xuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlLmdldDxUPihrZXkpLnBpcGUoXG4gICAgICAvKiBDaGVjayBpZiBgaW5kZXhlZERiYCBpcyBicm9rZW4gKi9cbiAgICAgIHRoaXMuY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5nZXQ8VD4oa2V5KSksXG4gICAgICBtZXJnZU1hcCgoZGF0YSkgPT4ge1xuXG4gICAgICAgIC8qIE5vIG5lZWQgdG8gdmFsaWRhdGUgaWYgdGhlIGRhdGEgaXMgZW1wdHkgKi9cbiAgICAgICAgaWYgKChkYXRhID09PSB1bmRlZmluZWQpIHx8IChkYXRhID09PSBudWxsKSkge1xuXG4gICAgICAgICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChzY2hlbWEpIHtcblxuICAgICAgICAgIC8qIFZhbGlkYXRlIGRhdGEgYWdhaW5zdCBhIEpTT04gc2NoZW1hIGlmIHByb3ZpZGVkICovXG4gICAgICAgICAgaWYgKCF0aGlzLmpzb25WYWxpZGF0b3IudmFsaWRhdGUoZGF0YSwgc2NoZW1hKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IobmV3IFZhbGlkYXRpb25FcnJvcigpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvKiBEYXRhIGhhdmUgYmVlbiBjaGVja2VkLCBzbyBpdCdzIE9LIHRvIGNhc3QgKi9cbiAgICAgICAgICByZXR1cm4gb2YoZGF0YSBhcyBUIHwgdW5kZWZpbmVkKTtcblxuICAgICAgICB9XG5cbiAgICAgICAgLyogQ2FzdCB0byB1bmtub3duIGFzIHRoZSBkYXRhIHdhc24ndCBjaGVja2VkICovXG4gICAgICAgIHJldHVybiBvZihkYXRhIGFzIHVua25vd24pO1xuXG4gICAgICB9KSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogU2V0IGFuIGl0ZW0gaW4gc3RvcmFnZS5cbiAgICogTm90ZSB0aGF0IHNldHRpbmcgYG51bGxgIG9yIGB1bmRlZmluZWRgIHdpbGwgcmVtb3ZlIHRoZSBpdGVtIHRvIGF2b2lkIHNvbWUgYnJvd3NlcnMgaXNzdWVzLlxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBkYXRhIFRoZSBpdGVtJ3MgdmFsdWVcbiAgICogQHBhcmFtIHNjaGVtYSBPcHRpb25hbCBKU09OIHNjaGVtYSB0byB2YWxpZGF0ZSB0aGUgZGF0YVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMuc3RvcmFnZU1hcC5zZXQoJ2tleScsICd2YWx1ZScpLnN1YnNjcmliZSgoKSA9PiB7fSk7XG4gICAqL1xuICBzZXQoa2V5OiBzdHJpbmcsIGRhdGE6IHVua25vd24sIHNjaGVtYT86IEpTT05TY2hlbWEpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgLyogU3RvcmluZyBgdW5kZWZpbmVkYCBvciBgbnVsbGAgaXMgdXNlbGVzcyBhbmQgY2FuIGNhdXNlIGlzc3VlcyBpbiBgaW5kZXhlZERiYCBpbiBzb21lIGJyb3dzZXJzLFxuICAgICAqIHNvIHJlbW92aW5nIGl0ZW0gaW5zdGVhZCBmb3IgYWxsIHN0b3JhZ2VzIHRvIGhhdmUgYSBjb25zaXN0ZW50IEFQSSAqL1xuICAgIGlmICgoZGF0YSA9PT0gdW5kZWZpbmVkKSB8fCAoZGF0YSA9PT0gbnVsbCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlbGV0ZShrZXkpO1xuICAgIH1cblxuICAgIC8qIFZhbGlkYXRlIGRhdGEgYWdhaW5zdCBhIEpTT04gc2NoZW1hIGlmIHByb3ZpZGVkICovXG4gICAgaWYgKHNjaGVtYSAmJiAhdGhpcy5qc29uVmFsaWRhdG9yLnZhbGlkYXRlKGRhdGEsIHNjaGVtYSkpIHtcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKG5ldyBWYWxpZGF0aW9uRXJyb3IoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2Uuc2V0KGtleSwgZGF0YSkucGlwZShcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgdGhpcy5jYXRjaElEQkJyb2tlbigoKSA9PiB0aGlzLmRhdGFiYXNlLnNldChrZXksIGRhdGEpKSxcbiAgICAgIC8qIE5vdGlmeSB3YXRjaGVycyAobXVzdCBiZSBsYXN0IGJlY2F1c2UgaXQgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHRoZSBvcGVyYXRpb24gc3VjY2VlZHMpICovXG4gICAgICB0YXAoKCkgPT4geyB0aGlzLm5vdGlmeShrZXksIGRhdGEpOyB9KSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhbiBpdGVtIGluIHN0b3JhZ2VcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHRoaXMuc3RvcmFnZU1hcC5kZWxldGUoJ2tleScpLnN1YnNjcmliZSgoKSA9PiB7fSk7XG4gICAqL1xuICBkZWxldGUoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UuZGVsZXRlKGtleSkucGlwZShcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgdGhpcy5jYXRjaElEQkJyb2tlbigoKSA9PiB0aGlzLmRhdGFiYXNlLmRlbGV0ZShrZXkpKSxcbiAgICAgIC8qIE5vdGlmeSB3YXRjaGVycyAobXVzdCBiZSBsYXN0IGJlY2F1c2UgaXQgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHRoZSBvcGVyYXRpb24gc3VjY2VlZHMpICovXG4gICAgICB0YXAoKCkgPT4geyB0aGlzLm5vdGlmeShrZXksIHVuZGVmaW5lZCk7IH0pLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYWxsIGl0ZW1zIGluIHN0b3JhZ2VcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuY2xlYXIoKS5zdWJzY3JpYmUoKCkgPT4ge30pO1xuICAgKi9cbiAgY2xlYXIoKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlLmNsZWFyKCkucGlwZShcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgdGhpcy5jYXRjaElEQkJyb2tlbigoKSA9PiB0aGlzLmRhdGFiYXNlLmNsZWFyKCkpLFxuICAgICAgLyogTm90aWZ5IHdhdGNoZXJzIChtdXN0IGJlIGxhc3QgYmVjYXVzZSBpdCBzaG91bGQgb25seSBoYXBwZW4gaWYgdGhlIG9wZXJhdGlvbiBzdWNjZWVkcykgKi9cbiAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHRoaXMubm90aWZpZXJzLmtleXMoKSkge1xuICAgICAgICAgIHRoaXMubm90aWZ5KGtleSwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwga2V5cyBzdG9yZWQgaW4gc3RvcmFnZS4gTm90ZSAqKnRoaXMgaXMgYW4gKml0ZXJhdGluZyogYE9ic2VydmFibGVgKio6XG4gICAqICogaWYgdGhlcmUgaXMgbm8ga2V5LCB0aGUgYG5leHRgIGNhbGxiYWNrIHdpbGwgbm90IGJlIGludm9rZWQsXG4gICAqICogaWYgeW91IG5lZWQgdG8gd2FpdCB0aGUgd2hvbGUgb3BlcmF0aW9uIHRvIGVuZCwgYmUgc3VyZSB0byBhY3QgaW4gdGhlIGBjb21wbGV0ZWAgY2FsbGJhY2ssXG4gICAqIGFzIHRoaXMgYE9ic2VydmFibGVgIGNhbiBlbWl0IHNldmVyYWwgdmFsdWVzIGFuZCBzbyB3aWxsIGludm9rZSB0aGUgYG5leHRgIGNhbGxiYWNrIHNldmVyYWwgdGltZXMuXG4gICAqIEByZXR1cm5zIEEgbGlzdCBvZiB0aGUga2V5cyB3cmFwcGVkIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWBcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLmtleXMoKS5zdWJzY3JpYmUoe1xuICAgKiAgIG5leHQ6IChrZXkpID0+IHsgY29uc29sZS5sb2coa2V5KTsgfSxcbiAgICogICBjb21wbGV0ZTogKCkgPT4geyBjb25zb2xlLmxvZygnRG9uZScpOyB9LFxuICAgKiB9KTtcbiAgICovXG4gIGtleXMoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcblxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlLmtleXMoKVxuICAgICAgLyogQ2F0Y2ggaWYgYGluZGV4ZWREYmAgaXMgYnJva2VuICovXG4gICAgICAucGlwZSh0aGlzLmNhdGNoSURCQnJva2VuKCgpID0+IHRoaXMuZGF0YWJhc2Uua2V5cygpKSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBUZWxscyBpZiBhIGtleSBleGlzdHMgaW4gc3RvcmFnZVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRlbGxpbmcgaWYgdGhlIGtleSBleGlzdHNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLmhhcygna2V5Jykuc3Vic2NyaWJlKChoYXNLZXkpID0+IHtcbiAgICogICBpZiAoaGFzS2V5KSB7fVxuICAgKiB9KTtcbiAgICovXG4gIGhhcyhrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UuaGFzKGtleSlcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgLnBpcGUodGhpcy5jYXRjaElEQkJyb2tlbigoKSA9PiB0aGlzLmRhdGFiYXNlLmhhcyhrZXkpKSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBXYXRjaCBhbiBpdGVtIHZhbHVlIGluIHN0b3JhZ2UuXG4gICAqICoqTm90ZSBvbmx5IGNoYW5nZXMgZG9uZSB2aWEgdGhpcyBsaWIgd2lsbCBiZSB3YXRjaGVkKiosIGV4dGVybmFsIGNoYW5nZXMgaW4gc3RvcmFnZSBjYW4ndCBiZSBkZXRlY3RlZC5cbiAgICogVGhlIHNpZ25hdHVyZSBoYXMgbWFueSBvdmVybG9hZHMgZHVlIHRvIHZhbGlkYXRpb24sICoqcGxlYXNlIHJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uLioqXG4gICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21hc3Rlci9kb2NzL1ZBTElEQVRJT04ubWRcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleSB0byB3YXRjaFxuICAgKiBAcGFyYW0gc2NoZW1hIE9wdGlvbmFsIEpTT04gc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBpbml0aWFsIHZhbHVlXG4gICAqIEByZXR1cm5zIEFuIGluZmluaXRlIGBPYnNlcnZhYmxlYCBnaXZpbmcgdGhlIGN1cnJlbnQgdmFsdWVcbiAgICovXG4gIHdhdGNoPFQgPSBzdHJpbmc+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFTdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZyB8IHVuZGVmaW5lZD47XG4gIHdhdGNoPFQgPSBudW1iZXI+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFJbnRlZ2VyIHwgSlNPTlNjaGVtYU51bWJlcik6IE9ic2VydmFibGU8bnVtYmVyIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCA9IGJvb2xlYW4+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFCb29sZWFuKTogT2JzZXJ2YWJsZTxib29sZWFuIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCA9IHN0cmluZ1tdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hU3RyaW5nPik6IE9ic2VydmFibGU8c3RyaW5nW10gfCB1bmRlZmluZWQ+O1xuICB3YXRjaDxUID0gbnVtYmVyW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFJbnRlZ2VyIHwgSlNPTlNjaGVtYU51bWJlcj4pOiBPYnNlcnZhYmxlPG51bWJlcltdIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCA9IGJvb2xlYW5bXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYUJvb2xlYW4+KTogT2JzZXJ2YWJsZTxib29sZWFuW10gfCB1bmRlZmluZWQ+O1xuICB3YXRjaDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIHdhdGNoPFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8dW5rbm93bj47XG4gIHdhdGNoPFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8dW5rbm93bj4ge1xuXG4gICAgLyogQ2hlY2sgaWYgdGhlcmUgaXMgYWxyZWFkeSBhIG5vdGlmaWVyIGFuZCBjYXN0IGFjY29yZGluZyB0byBzY2hlbWEgKi9cbiAgICBsZXQgbm90aWZpZXIgPSB0aGlzLm5vdGlmaWVycy5nZXQoa2V5KSBhcyBSZXBsYXlTdWJqZWN0PHR5cGVvZiBzY2hlbWEgZXh0ZW5kcyBKU09OU2NoZW1hID8gKFQgfCB1bmRlZmluZWQpIDogdW5rbm93bj47XG5cbiAgICBpZiAoIW5vdGlmaWVyKSB7XG5cbiAgICAgIC8qIENyZWF0ZSBhIG5vdGlmaWVyIGFuZCBjYXN0IGFjY29yZGluZyB0byBzY2hlbWEgKi9cbiAgICAgIG5vdGlmaWVyID0gbmV3IFJlcGxheVN1YmplY3Q8dHlwZW9mIHNjaGVtYSBleHRlbmRzIEpTT05TY2hlbWEgPyAoVCB8IHVuZGVmaW5lZCkgOiB1bmtub3duPigxKTtcblxuICAgICAgLyogTWVtb3JpemUgdGhlIG5vdGlmaWVyICovXG4gICAgICB0aGlzLm5vdGlmaWVycy5zZXQoa2V5LCBub3RpZmllcik7XG5cbiAgICAgIC8qIEdldCB0aGUgY3VycmVudCBpdGVtIHZhbHVlICovXG4gICAgICB0aGlzLmdldDxUPihrZXksIHNjaGVtYSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlc3VsdCkgPT4gbm90aWZpZXIubmV4dChyZXN1bHQpLFxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiBub3RpZmllci5lcnJvcihlcnJvciksXG4gICAgICB9KTtcblxuICAgIH1cblxuICAgIC8qIE9ubHkgdGhlIHB1YmxpYyBBUEkgb2YgdGhlIGBPYnNlcnZhYmxlYCBzaG91bGQgYmUgcmV0dXJuZWQgKi9cbiAgICByZXR1cm4gbm90aWZpZXIuYXNPYnNlcnZhYmxlKCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZnkgd2hlbiBhIHZhbHVlIGNoYW5nZXNcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gZGF0YSBUaGUgbmV3IHZhbHVlXG4gICAqL1xuICBwcm90ZWN0ZWQgbm90aWZ5KGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuXG4gICAgY29uc3Qgbm90aWZpZXIgPSB0aGlzLm5vdGlmaWVycy5nZXQoa2V5KTtcblxuICAgIGlmIChub3RpZmllcikge1xuICAgICAgbm90aWZpZXIubmV4dCh2YWx1ZSk7XG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogUnhKUyBvcGVyYXRvciB0byBjYXRjaCBpZiBgaW5kZXhlZERCYCBpcyBicm9rZW5cbiAgICogQHBhcmFtIG9wZXJhdGlvbkNhbGxiYWNrIENhbGxiYWNrIHdpdGggdGhlIG9wZXJhdGlvbiB0byByZWRvXG4gICAqL1xuICBwcm90ZWN0ZWQgY2F0Y2hJREJCcm9rZW48VD4ob3BlcmF0aW9uQ2FsbGJhY2s6ICgpID0+IE9ic2VydmFibGU8VD4pOiBPcGVyYXRvckZ1bmN0aW9uPFQsIFQ+IHtcblxuICAgIHJldHVybiBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuXG4gICAgICAvKiBDaGVjayBpZiBgaW5kZXhlZERCYCBpcyBicm9rZW4gYmFzZWQgb24gZXJyb3IgbWVzc2FnZSAodGhlIHNwZWNpZmljIGVycm9yIGNsYXNzIHNlZW1zIHRvIGJlIGxvc3QgaW4gdGhlIHByb2Nlc3MpICovXG4gICAgICBpZiAoKGVycm9yICE9PSB1bmRlZmluZWQpICYmIChlcnJvciAhPT0gbnVsbCkgJiYgKGVycm9yLm1lc3NhZ2UgPT09IElEQl9CUk9LRU5fRVJST1IpKSB7XG5cbiAgICAgICAgLyogV2hlbiBzdG9yYWdlIGlzIGZ1bGx5IGRpc2FibGVkIGluIGJyb3dzZXIgKHZpYSB0aGUgXCJCbG9jayBhbGwgY29va2llc1wiIG9wdGlvbiksXG4gICAgICAgICAqIGp1c3QgdHJ5aW5nIHRvIGNoZWNrIGBsb2NhbFN0b3JhZ2VgIHZhcmlhYmxlIGNhdXNlcyBhIHNlY3VyaXR5IGV4Y2VwdGlvbi5cbiAgICAgICAgICogUHJldmVudHMgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvMTE4XG4gICAgICAgICAqL1xuICAgICAgICB0cnkge1xuXG4gICAgICAgICAgaWYgKCdnZXRJdGVtJyBpbiBsb2NhbFN0b3JhZ2UpIHtcblxuICAgICAgICAgICAgLyogRmFsbGJhY2sgdG8gYGxvY2FsU3RvcmFnZWAgaWYgYXZhaWxhYmxlICovXG4gICAgICAgICAgICB0aGlzLmRhdGFiYXNlID0gbmV3IExvY2FsU3RvcmFnZURhdGFiYXNlKHRoaXMuTFNQcmVmaXgpO1xuXG4gICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgLyogRmFsbGJhY2sgdG8gbWVtb3J5IHN0b3JhZ2Ugb3RoZXJ3aXNlICovXG4gICAgICAgICAgICB0aGlzLmRhdGFiYXNlID0gbmV3IE1lbW9yeURhdGFiYXNlKCk7XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBjYXRjaCB7XG5cbiAgICAgICAgICAvKiBGYWxsYmFjayB0byBtZW1vcnkgc3RvcmFnZSBvdGhlcndpc2UgKi9cbiAgICAgICAgICB0aGlzLmRhdGFiYXNlID0gbmV3IE1lbW9yeURhdGFiYXNlKCk7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIC8qIFJlZG8gdGhlIG9wZXJhdGlvbiAqL1xuICAgICAgICByZXR1cm4gb3BlcmF0aW9uQ2FsbGJhY2soKTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICAvKiBPdGhlcndpc2UsIHJldGhyb3cgdGhlIGVycm9yICovXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yKTtcblxuICAgICAgfVxuXG4gICAgfSk7XG5cbiAgfVxuXG59XG4iXX0=

@@ -5,234 +5,237 @@ import { __decorate } from "tslib";

// TODO: detailed error messages?
let JSONValidator = class JSONValidator {
/**
* Validate a JSON data against a Jsubset of the JSON Schema standard.
* Types are enforced to validate everything: each schema must
* @param data JSON data to validate
* @param schema Subset of JSON Schema. Must have a `type`.
* @returns If data is valid: `true`, if it is invalid: `false`
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/VALIDATION.md}
*/
validate(data, schema) {
switch (schema.type) {
case 'string':
return this.validateString(data, schema);
case 'number':
case 'integer':
return this.validateNumber(data, schema);
case 'boolean':
return this.validateBoolean(data, schema);
case 'array':
return this.validateArray(data, schema);
case 'object':
return this.validateObject(data, schema);
let JSONValidator = /** @class */ (() => {
let JSONValidator = class JSONValidator {
/**
* Validate a JSON data against a Jsubset of the JSON Schema standard.
* Types are enforced to validate everything: each schema must
* @param data JSON data to validate
* @param schema Subset of JSON Schema. Must have a `type`.
* @returns If data is valid: `true`, if it is invalid: `false`
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/VALIDATION.md}
*/
validate(data, schema) {
switch (schema.type) {
case 'string':
return this.validateString(data, schema);
case 'number':
case 'integer':
return this.validateNumber(data, schema);
case 'boolean':
return this.validateBoolean(data, schema);
case 'array':
return this.validateArray(data, schema);
case 'object':
return this.validateObject(data, schema);
}
}
}
/**
* Validate a string
* @param data Data to validate
* @param schema Schema describing the string
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateString(data, schema) {
if (typeof data !== 'string') {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
if (!this.validateEnum(data, schema)) {
return false;
}
if ((schema.maxLength !== undefined) && (data.length > schema.maxLength)) {
return false;
}
if ((schema.minLength !== undefined) && (data.length < schema.minLength)) {
return false;
}
if (schema.pattern) {
let regularExpression = null;
try {
regularExpression = new RegExp(schema.pattern);
/**
* Validate a string
* @param data Data to validate
* @param schema Schema describing the string
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateString(data, schema) {
if (typeof data !== 'string') {
return false;
}
catch (_a) { }
if (regularExpression && !regularExpression.test(data)) {
if (!this.validateConst(data, schema)) {
return false;
}
}
return true;
}
/**
* Validate a number or an integer
* @param data Data to validate
* @param schema Schema describing the number or integer
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateNumber(data, schema) {
if (typeof data !== 'number') {
return false;
}
if ((schema.type === 'integer') && !Number.isInteger(data)) {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
if (!this.validateEnum(data, schema)) {
return false;
}
/* Test is done this way to not divide by 0 */
if (schema.multipleOf && !Number.isInteger(data / schema.multipleOf)) {
return false;
}
if ((schema.maximum !== undefined) && (data > schema.maximum)) {
return false;
}
if ((schema.exclusiveMaximum !== undefined) && (data >= schema.exclusiveMaximum)) {
return false;
}
if ((schema.minimum !== undefined) && (data < schema.minimum)) {
return false;
}
if ((schema.exclusiveMinimum !== undefined) && (data <= schema.exclusiveMinimum)) {
return false;
}
return true;
}
/**
* Validate a boolean
* @param data Data to validate
* @param schema Schema describing the boolean
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateBoolean(data, schema) {
if (typeof data !== 'boolean') {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
return true;
}
/**
* Validate an array
* @param data Data to validate
* @param schema Schema describing the array
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateArray(data, schema) {
if (!Array.isArray(data)) {
return false;
}
if ((schema.maxItems !== undefined) && (data.length > schema.maxItems)) {
return false;
}
if ((schema.minItems !== undefined) && (data.length < schema.minItems)) {
return false;
}
if (schema.uniqueItems) {
/* Create a set to eliminate values with multiple occurences */
const dataSet = new Set(data);
if (data.length !== dataSet.size) {
if (!this.validateEnum(data, schema)) {
return false;
}
if ((schema.maxLength !== undefined) && (data.length > schema.maxLength)) {
return false;
}
if ((schema.minLength !== undefined) && (data.length < schema.minLength)) {
return false;
}
if (schema.pattern) {
let regularExpression = null;
try {
regularExpression = new RegExp(schema.pattern);
}
catch (_a) { }
if (regularExpression && !regularExpression.test(data)) {
return false;
}
}
return true;
}
/* Specific test for tuples */
if (Array.isArray(schema.items)) {
return this.validateTuple(data, schema.items);
}
/* Validate all the values in array */
for (const value of data) {
if (!this.validate(value, schema.items)) {
/**
* Validate a number or an integer
* @param data Data to validate
* @param schema Schema describing the number or integer
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateNumber(data, schema) {
if (typeof data !== 'number') {
return false;
}
if ((schema.type === 'integer') && !Number.isInteger(data)) {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
if (!this.validateEnum(data, schema)) {
return false;
}
/* Test is done this way to not divide by 0 */
if (schema.multipleOf && !Number.isInteger(data / schema.multipleOf)) {
return false;
}
if ((schema.maximum !== undefined) && (data > schema.maximum)) {
return false;
}
if ((schema.exclusiveMaximum !== undefined) && (data >= schema.exclusiveMaximum)) {
return false;
}
if ((schema.minimum !== undefined) && (data < schema.minimum)) {
return false;
}
if ((schema.exclusiveMinimum !== undefined) && (data <= schema.exclusiveMinimum)) {
return false;
}
return true;
}
return true;
}
/**
* Validate a tuple (array with fixed length and multiple types)
* @param data Data to validate
* @param schemas Schemas describing the tuple
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateTuple(data, schemas) {
/* Tuples have a fixed length */
if (data.length !== schemas.length) {
return false;
}
for (let i = 0; i < schemas.length; i += 1) {
if (!this.validate(data[i], schemas[i])) {
/**
* Validate a boolean
* @param data Data to validate
* @param schema Schema describing the boolean
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateBoolean(data, schema) {
if (typeof data !== 'boolean') {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
return true;
}
return true;
}
/**
* Validate an object
* @param data Data to validate
* @param schema JSON schema describing the object
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateObject(data, schema) {
/* Check the type and if not `null` as `null` also have the type `object` in old browsers */
if ((typeof data !== 'object') || (data === null)) {
return false;
}
/* Check if the object doesn't have more properties than expected
* Equivalent of `additionalProperties: false`
/**
* Validate an array
* @param data Data to validate
* @param schema Schema describing the array
* @returns If data is valid: `true`, if it is invalid: `false`
*/
if (Object.keys(schema.properties).length < Object.keys(data).length) {
return false;
}
/* Validate required properties */
if (schema.required) {
for (const requiredProp of schema.required) {
if (!data.hasOwnProperty(requiredProp)) {
validateArray(data, schema) {
if (!Array.isArray(data)) {
return false;
}
if ((schema.maxItems !== undefined) && (data.length > schema.maxItems)) {
return false;
}
if ((schema.minItems !== undefined) && (data.length < schema.minItems)) {
return false;
}
if (schema.uniqueItems) {
/* Create a set to eliminate values with multiple occurences */
const dataSet = new Set(data);
if (data.length !== dataSet.size) {
return false;
}
}
/* Specific test for tuples */
if (Array.isArray(schema.items)) {
return this.validateTuple(data, schema.items);
}
/* Validate all the values in array */
for (const value of data) {
if (!this.validate(value, schema.items)) {
return false;
}
}
return true;
}
/* Recursively validate all properties */
for (const property in schema.properties) {
/* Filter to keep only real properties (no internal JS stuff) and check if the data has the property too */
if (schema.properties.hasOwnProperty(property) && data.hasOwnProperty(property)) {
if (!this.validate(data[property], schema.properties[property])) {
/**
* Validate a tuple (array with fixed length and multiple types)
* @param data Data to validate
* @param schemas Schemas describing the tuple
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateTuple(data, schemas) {
/* Tuples have a fixed length */
if (data.length !== schemas.length) {
return false;
}
for (let i = 0; i < schemas.length; i += 1) {
if (!this.validate(data[i], schemas[i])) {
return false;
}
}
}
return true;
}
/**
* Validate a constant
* @param data Data ta validate
* @param schema JSON schema describing the constant
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateConst(data, schema) {
if (!schema.const) {
return true;
}
return (data === schema.const);
}
/**
* Validate an enum
* @param data Data ta validate
* @param schema JSON schema describing the enum
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateEnum(data, schema) {
if (!schema.enum) {
/**
* Validate an object
* @param data Data to validate
* @param schema JSON schema describing the object
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateObject(data, schema) {
/* Check the type and if not `null` as `null` also have the type `object` in old browsers */
if ((typeof data !== 'object') || (data === null)) {
return false;
}
/* Check if the object doesn't have more properties than expected
* Equivalent of `additionalProperties: false`
*/
if (Object.keys(schema.properties).length < Object.keys(data).length) {
return false;
}
/* Validate required properties */
if (schema.required) {
for (const requiredProp of schema.required) {
if (!data.hasOwnProperty(requiredProp)) {
return false;
}
}
}
/* Recursively validate all properties */
for (const property in schema.properties) {
/* Filter to keep only real properties (no internal JS stuff) and check if the data has the property too */
if (schema.properties.hasOwnProperty(property) && data.hasOwnProperty(property)) {
if (!this.validate(data[property], schema.properties[property])) {
return false;
}
}
}
return true;
}
/* Cast as the data can be of multiple types, and so TypeScript is lost */
return (schema.enum.includes(data));
}
};
JSONValidator.ɵprov = i0.ɵɵdefineInjectable({ factory: function JSONValidator_Factory() { return new JSONValidator(); }, token: JSONValidator, providedIn: "root" });
JSONValidator = __decorate([
Injectable({
providedIn: 'root'
})
], JSONValidator);
/**
* Validate a constant
* @param data Data ta validate
* @param schema JSON schema describing the constant
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateConst(data, schema) {
if (!schema.const) {
return true;
}
return (data === schema.const);
}
/**
* Validate an enum
* @param data Data ta validate
* @param schema JSON schema describing the enum
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateEnum(data, schema) {
if (!schema.enum) {
return true;
}
/* Cast as the data can be of multiple types, and so TypeScript is lost */
return (schema.enum.includes(data));
}
};
JSONValidator.ɵprov = i0.ɵɵdefineInjectable({ factory: function JSONValidator_Factory() { return new JSONValidator(); }, token: JSONValidator, providedIn: "root" });
JSONValidator = __decorate([
Injectable({
providedIn: 'root'
})
], JSONValidator);
return JSONValidator;
})();
export { JSONValidator };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi12YWxpZGF0b3IuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LXB3YS9sb2NhbC1zdG9yYWdlLyIsInNvdXJjZXMiOlsibGliL3ZhbGlkYXRpb24vanNvbi12YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBTzNDLGlDQUFpQztBQUlqQyxJQUFhLGFBQWEsR0FBMUIsTUFBYSxhQUFhO0lBRXhCOzs7Ozs7O09BT0c7SUFDSCxRQUFRLENBQUMsSUFBYSxFQUFFLE1BQWtCO1FBRXhDLFFBQVEsTUFBTSxDQUFDLElBQUksRUFBRTtZQUVuQixLQUFLLFFBQVE7Z0JBQ1gsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMzQyxLQUFLLFFBQVEsQ0FBQztZQUNkLEtBQUssU0FBUztnQkFDWixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzNDLEtBQUssU0FBUztnQkFDWixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVDLEtBQUssT0FBTztnQkFDVixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzFDLEtBQUssUUFBUTtnQkFDWCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBRTVDO0lBRUgsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ08sY0FBYyxDQUFDLElBQWEsRUFBRSxNQUF3QjtRQUU5RCxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRTtZQUM1QixPQUFPLEtBQUssQ0FBQztTQUNkO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQ3JDLE9BQU8sS0FBSyxD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QUVGO1NBRUY7UUFFRCx5Q0FBeUM7UUFDekMsS0FBSyxNQUFNLFFBQVEsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO1lBRXhDLDJHQUEyRztZQUMzRyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUU7Z0JBRS9FLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFFLElBQWtDLENBQUMsUUFBUSxDQUFDLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFO29CQUM5RixPQUFPLEtBQUssQ0FBQztpQkFDZDthQUVGO1NBRUY7UUFFRCxPQUFPLElBQUksQ0FBQztJQUVkLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNPLGFBQWEsQ0FBQyxJQUFhLEVBQUUsTUFBbUY7UUFFeEgsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7WUFDakIsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUVELE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRWpDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNPLFlBQVksQ0FBQyxJQUFhLEVBQUUsTUFBK0Q7UUFFbkcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUU7WUFDaEIsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUVELDBFQUEwRTtRQUMxRSxPQUFPLENBQUUsTUFBTSxDQUFDLElBQWtCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFFckQsQ0FBQztDQUVGLENBQUE7O0FBclRZLGFBQWE7SUFIekIsVUFBVSxDQUFDO1FBQ1YsVUFBVSxFQUFFLE1BQU07S0FDbkIsQ0FBQztHQUNXLGFBQWEsQ0FxVHpCO1NBclRZLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7XG4gIEpTT05TY2hlbWEsIEpTT05TY2hlbWFTdHJpbmcsIEpTT05TY2hlbWFJbnRlZ2VyLCBKU09OU2NoZW1hTnVtYmVyLCBKU09OU2NoZW1hQm9vbGVhbixcbiAgSlNPTlNjaGVtYUFycmF5LCBKU09OU2NoZW1hT2JqZWN0XG59IGZyb20gJy4vanNvbi1zY2hlbWEnO1xuXG4vLyBUT0RPOiBkZXRhaWxlZCBlcnJvciBtZXNzYWdlcz9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEpTT05WYWxpZGF0b3Ige1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIEpTT04gZGF0YSBhZ2FpbnN0IGEgSnN1YnNldCBvZiB0aGUgSlNPTiBTY2hlbWEgc3RhbmRhcmQuXG4gICAqIFR5cGVzIGFyZSBlbmZvcmNlZCB0byB2YWxpZGF0ZSBldmVyeXRoaW5nOiBlYWNoIHNjaGVtYSBtdXN0XG4gICAqIEBwYXJhbSBkYXRhIEpTT04gZGF0YSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0gc2NoZW1hIFN1YnNldCBvZiBKU09OIFNjaGVtYS4gTXVzdCBoYXZlIGEgYHR5cGVgLlxuICAgKiBAcmV0dXJucyBJZiBkYXRhIGlzIHZhbGlkOiBgdHJ1ZWAsIGlmIGl0IGlzIGludmFsaWQ6IGBmYWxzZWBcbiAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21hc3Rlci9kb2NzL1ZBTElEQVRJT04ubWR9XG4gICAqL1xuICB2YWxpZGF0ZShkYXRhOiB1bmtub3duLCBzY2hlbWE6IEpTT05TY2hlbWEpOiBib29sZWFuIHtcblxuICAgIHN3aXRjaCAoc2NoZW1hLnR5cGUpIHtcblxuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGVTdHJpbmcoZGF0YSwgc2NoZW1hKTtcbiAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGVOdW1iZXIoZGF0YSwgc2NoZW1hKTtcbiAgICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUJvb2xlYW4oZGF0YSwgc2NoZW1hKTtcbiAgICAgIGNhc2UgJ2FycmF5JzpcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGVBcnJheShkYXRhLCBzY2hlbWEpO1xuICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGVPYmplY3QoZGF0YSwgc2NoZW1hKTtcblxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGEgc3RyaW5nXG4gICAqIEBwYXJhbSBkYXRhIERhdGEgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHNjaGVtYSBTY2hlbWEgZGVzY3JpYmluZyB0aGUgc3RyaW5nXG4gICAqIEByZXR1cm5zIElmIGRhdGEgaXMgdmFsaWQ6IGB0cnVlYCwgaWYgaXQgaXMgaW52YWxpZDogYGZhbHNlYFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlU3RyaW5nKGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYVN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghdGhpcy52YWxpZGF0ZUNvbnN0KGRhdGEsIHNjaGVtYSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMudmFsaWRhdGVFbnVtKGRhdGEsIHNjaGVtYSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoKHNjaGVtYS5tYXhMZW5ndGggIT09IHVuZGVmaW5lZCkgJiYgKGRhdGEubGVuZ3RoID4gc2NoZW1hLm1heExlbmd0aCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoKHNjaGVtYS5taW5MZW5ndGggIT09IHVuZGVmaW5lZCkgJiYgKGRhdGEubGVuZ3RoIDwgc2NoZW1hLm1pbkxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hLnBhdHRlcm4pIHtcblxuICAgICAgbGV0IHJlZ3VsYXJFeHByZXNzaW9uOiBSZWdFeHAgfCBudWxsID0gbnVsbDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmVndWxhckV4cHJlc3Npb24gPSBuZXcgUmVnRXhwKHNjaGVtYS5wYXR0ZXJuKTtcbiAgICAgIH0gY2F0Y2gge31cblxuICAgICAgaWYgKHJlZ3VsYXJFeHByZXNzaW9uICYmICFyZWd1bGFyRXhwcmVzc2lvbi50ZXN0KGRhdGEpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuXG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYSBudW1iZXIgb3IgYW4gaW50ZWdlclxuICAgKiBAcGFyYW0gZGF0YSBEYXRhIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBzY2hlbWEgU2NoZW1hIGRlc2NyaWJpbmcgdGhlIG51bWJlciBvciBpbnRlZ2VyXG4gICAqIEByZXR1cm5zIElmIGRhdGEgaXMgdmFsaWQ6IGB0cnVlYCwgaWYgaXQgaXMgaW52YWxpZDogYGZhbHNlYFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlTnVtYmVyKGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYU51bWJlciB8wqBKU09OU2NoZW1hSW50ZWdlcik6IGJvb2xlYW4ge1xuXG4gICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICgoc2NoZW1hLnR5cGUgPT09ICdpbnRlZ2VyJykgJiYgIU51bWJlci5pc0ludGVnZXIoZGF0YSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMudmFsaWRhdGVDb25zdChkYXRhLCBzY2hlbWEpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnZhbGlkYXRlRW51bShkYXRhLCBzY2hlbWEpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyogVGVzdCBpcyBkb25lIHRoaXMgd2F5IHRvIG5vdCBkaXZpZGUgYnkgMCAqL1xuICAgIGlmIChzY2hlbWEubXVsdGlwbGVPZiAmJiAhTnVtYmVyLmlzSW50ZWdlcihkYXRhIC8gc2NoZW1hLm11bHRpcGxlT2YpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKChzY2hlbWEubWF4aW11bSAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YSA+IHNjaGVtYS5tYXhpbXVtKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKChzY2hlbWEuZXhjbHVzaXZlTWF4aW11bSAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YSA+PSBzY2hlbWEuZXhjbHVzaXZlTWF4aW11bSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIH1cblxuICAgIGlmICgoc2NoZW1hLm1pbmltdW0gIT09IHVuZGVmaW5lZCkgJiYgKGRhdGEgPCBzY2hlbWEubWluaW11bSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIH1cblxuICAgIGlmICgoc2NoZW1hLmV4Y2x1c2l2ZU1pbmltdW0gIT09IHVuZGVmaW5lZCkgJiYgKGRhdGEgPD0gc2NoZW1hLmV4Y2x1c2l2ZU1pbmltdW0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGEgYm9vbGVhblxuICAgKiBAcGFyYW0gZGF0YSBEYXRhIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBzY2hlbWEgU2NoZW1hIGRlc2NyaWJpbmcgdGhlIGJvb2xlYW5cbiAgICogQHJldHVybnMgSWYgZGF0YSBpcyB2YWxpZDogYHRydWVgLCBpZiBpdCBpcyBpbnZhbGlkOiBgZmFsc2VgXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVCb29sZWFuKGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYUJvb2xlYW4pOiBib29sZWFuIHtcblxuICAgIGlmICh0eXBlb2YgZGF0YSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnZhbGlkYXRlQ29uc3QoZGF0YSwgc2NoZW1hKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuXG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYW4gYXJyYXlcbiAgICogQHBhcmFtIGRhdGEgRGF0YSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0gc2NoZW1hIFNjaGVtYSBkZXNjcmliaW5nIHRoZSBhcnJheVxuICAgKiBAcmV0dXJucyBJZiBkYXRhIGlzIHZhbGlkOiBgdHJ1ZWAsIGlmIGl0IGlzIGludmFsaWQ6IGBmYWxzZWBcbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZUFycmF5KGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5KTogYm9vbGVhbiB7XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoKHNjaGVtYS5tYXhJdGVtcyAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YS5sZW5ndGggPiBzY2hlbWEubWF4SXRlbXMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKChzY2hlbWEubWluSXRlbXMgIT09IHVuZGVmaW5lZCkgJiYgKGRhdGEubGVuZ3RoIDwgc2NoZW1hLm1pbkl0ZW1zKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWEudW5pcXVlSXRlbXMpIHtcblxuICAgICAgLyogQ3JlYXRlIGEgc2V0IHRvIGVsaW1pbmF0ZSB2YWx1ZXMgd2l0aCBtdWx0aXBsZSBvY2N1cmVuY2VzICovXG4gICAgICBjb25zdCBkYXRhU2V0ID0gbmV3IFNldChkYXRhKTtcblxuICAgICAgaWYgKGRhdGEubGVuZ3RoICE9PSBkYXRhU2V0LnNpemUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgfVxuXG4gICAgLyogU3BlY2lmaWMgdGVzdCBmb3IgdHVwbGVzICovXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVR1cGxlKGRhdGEsIHNjaGVtYS5pdGVtcyk7XG5cbiAgICB9XG5cbiAgICAvKiBWYWxpZGF0ZSBhbGwgdGhlIHZhbHVlcyBpbiBhcnJheSAqL1xuICAgIGZvciAoY29uc3QgdmFsdWUgb2YgZGF0YSkge1xuXG4gICAgICBpZiAoIXRoaXMudmFsaWRhdGUodmFsdWUsIHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIHR1cGxlIChhcnJheSB3aXRoIGZpeGVkIGxlbmd0aCBhbmQgbXVsdGlwbGUgdHlwZXMpXG4gICAqIEBwYXJhbSBkYXRhIERhdGEgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHNjaGVtYXMgU2NoZW1hcyBkZXNjcmliaW5nIHRoZSB0dXBsZVxuICAgKiBAcmV0dXJucyBJZiBkYXRhIGlzIHZhbGlkOiBgdHJ1ZWAsIGlmIGl0IGlzIGludmFsaWQ6IGBmYWxzZWBcbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZVR1cGxlKGRhdGE6IHVua25vd25bXSwgc2NoZW1hczogSlNPTlNjaGVtYVtdKTogYm9vbGVhbiB7XG5cbiAgICAvKiBUdXBsZXMgaGF2ZSBhIGZpeGVkIGxlbmd0aCAqL1xuICAgIGlmIChkYXRhLmxlbmd0aCAhPT0gc2NoZW1hcy5sZW5ndGgpIHtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzY2hlbWFzLmxlbmd0aDsgaSArPSAxKSB7XG5cbiAgICAgIGlmICghdGhpcy52YWxpZGF0ZShkYXRhW2ldLCBzY2hlbWFzW2ldKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGFuIG9iamVjdFxuICAgKiBAcGFyYW0gZGF0YSBEYXRhIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBzY2hlbWEgSlNPTiBzY2hlbWEgZGVzY3JpYmluZyB0aGUgb2JqZWN0XG4gICAqIEByZXR1cm5zIElmIGRhdGEgaXMgdmFsaWQ6IGB0cnVlYCwgaWYgaXQgaXMgaW52YWxpZDogYGZhbHNlYFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlT2JqZWN0KGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYU9iamVjdCk6IGJvb2xlYW4ge1xuXG4gICAgLyogQ2hlY2sgdGhlIHR5cGUgYW5kIGlmIG5vdCBgbnVsbGAgYXMgYG51bGxgIGFsc28gaGF2ZSB0aGUgdHlwZSBgb2JqZWN0YCBpbiBvbGQgYnJvd3NlcnMgKi9cbiAgICBpZiAoKHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0JykgfHwgKGRhdGEgPT09IG51bGwpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyogQ2hlY2sgaWYgdGhlIG9iamVjdCBkb2Vzbid0IGhhdmUgbW9yZSBwcm9wZXJ0aWVzIHRoYW4gZXhwZWN0ZWRcbiAgICAgKiBFcXVpdmFsZW50IG9mIGBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2VgXG4gICAgICovXG4gICAgaWYgKE9iamVjdC5rZXlzKHNjaGVtYS5wcm9wZXJ0aWVzKS5sZW5ndGggPCBPYmplY3Qua2V5cyhkYXRhKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKiBWYWxpZGF0ZSByZXF1aXJlZCBwcm9wZXJ0aWVzICovXG4gICAgaWYgKHNjaGVtYS5yZXF1aXJlZCkge1xuXG4gICAgICBmb3IgKGNvbnN0IHJlcXVpcmVkUHJvcCBvZiBzY2hlbWEucmVxdWlyZWQpIHtcblxuICAgICAgICBpZiAoIWRhdGEuaGFzT3duUHJvcGVydHkocmVxdWlyZWRQcm9wKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICB9XG5cbiAgICB9XG5cbiAgICAvKiBSZWN1cnNpdmVseSB2YWxpZGF0ZSBhbGwgcHJvcGVydGllcyAqL1xuICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gc2NoZW1hLnByb3BlcnRpZXMpIHtcblxuICAgICAgLyogRmlsdGVyIHRvIGtlZXAgb25seSByZWFsIHByb3BlcnRpZXMgKG5vIGludGVybmFsIEpTIHN0dWZmKSBhbmQgY2hlY2sgaWYgdGhlIGRhdGEgaGFzIHRoZSBwcm9wZXJ0eSB0b28gKi9cbiAgICAgIGlmIChzY2hlbWEucHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eSkgJiYgZGF0YS5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eSkpIHtcblxuICAgICAgICBpZiAoIXRoaXMudmFsaWRhdGUoKGRhdGEgYXMgeyBbazogc3RyaW5nXTogdW5rbm93bjsgfSlbcHJvcGVydHldLCBzY2hlbWEucHJvcGVydGllc1twcm9wZXJ0eV0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgIH1cblxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuXG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYSBjb25zdGFudFxuICAgKiBAcGFyYW0gZGF0YSBEYXRhIHRhIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBzY2hlbWEgSlNPTiBzY2hlbWEgZGVzY3JpYmluZyB0aGUgY29uc3RhbnRcbiAgICogQHJldHVybnMgSWYgZGF0YSBpcyB2YWxpZDogYHRydWVgLCBpZiBpdCBpcyBpbnZhbGlkOiBgZmFsc2VgXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVDb25zdChkYXRhOiB1bmtub3duLCBzY2hlbWE6IEpTT05TY2hlbWFCb29sZWFuIHwgSlNPTlNjaGVtYUludGVnZXIgfCBKU09OU2NoZW1hTnVtYmVyIHwgSlNPTlNjaGVtYVN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgaWYgKCFzY2hlbWEuY29uc3QpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiAoZGF0YSA9PT0gc2NoZW1hLmNvbnN0KTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGFuIGVudW1cbiAgICogQHBhcmFtIGRhdGEgRGF0YSB0YSB2YWxpZGF0ZVxuICAgKiBAcGFyYW0gc2NoZW1hIEpTT04gc2NoZW1hIGRlc2NyaWJpbmcgdGhlIGVudW1cbiAgICogQHJldHVybnMgSWYgZGF0YSBpcyB2YWxpZDogYHRydWVgLCBpZiBpdCBpcyBpbnZhbGlkOiBgZmFsc2VgXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVFbnVtKGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYUludGVnZXIgfCBKU09OU2NoZW1hTnVtYmVyIHwgSlNPTlNjaGVtYVN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgaWYgKCFzY2hlbWEuZW51bSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyogQ2FzdCBhcyB0aGUgZGF0YSBjYW4gYmUgb2YgbXVsdGlwbGUgdHlwZXMsIGFuZCBzbyBUeXBlU2NyaXB0IGlzIGxvc3QgKi9cbiAgICByZXR1cm4gKChzY2hlbWEuZW51bSBhcyB1bmtub3duW10pLmluY2x1ZGVzKGRhdGEpKTtcblxuICB9XG5cbn1cbiJdfQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi12YWxpZGF0b3IuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LXB3YS9sb2NhbC1zdG9yYWdlLyIsInNvdXJjZXMiOlsibGliL3ZhbGlkYXRpb24vanNvbi12YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBTzNDLGlDQUFpQztBQUlqQztJQUFBLElBQWEsYUFBYSxHQUExQixNQUFhLGFBQWE7UUFFeEI7Ozs7Ozs7V0FPRztRQUNILFFBQVEsQ0FBQyxJQUFhLEVBQUUsTUFBa0I7WUFFeEMsUUFBUSxNQUFNLENBQUMsSUFBSSxFQUFFO2dCQUVuQixLQUFLLFFBQVE7b0JBQ1gsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDM0MsS0FBSyxRQUFRLENBQUM7Z0JBQ2QsS0FBSyxTQUFTO29CQUNaLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzNDLEtBQUssU0FBUztvQkFDWixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUM1QyxLQUFLLE9BQU87b0JBQ1YsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDMUMsS0FBSyxRQUFRO29CQUNYLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7YUFFNUM7UUFFSCxDQUFDO1FBRUQ7Ozs7O1dBS0c7UUFDTyxjQUFjLENBQUMsSUFBYSxFQUFFLE1BQXdCO1lBRTlELElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFO2dCQUM1QixPQUFPLEtBQUssQ0FBQzthQUNkO1lBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFO2dCQUNy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IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtcbiAgSlNPTlNjaGVtYSwgSlNPTlNjaGVtYVN0cmluZywgSlNPTlNjaGVtYUludGVnZXIsIEpTT05TY2hlbWFOdW1iZXIsIEpTT05TY2hlbWFCb29sZWFuLFxuICBKU09OU2NoZW1hQXJyYXksIEpTT05TY2hlbWFPYmplY3Rcbn0gZnJvbSAnLi9qc29uLXNjaGVtYSc7XG5cbi8vIFRPRE86IGRldGFpbGVkIGVycm9yIG1lc3NhZ2VzP1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgSlNPTlZhbGlkYXRvciB7XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGEgSlNPTiBkYXRhIGFnYWluc3QgYSBKc3Vic2V0IG9mIHRoZSBKU09OIFNjaGVtYSBzdGFuZGFyZC5cbiAgICogVHlwZXMgYXJlIGVuZm9yY2VkIHRvIHZhbGlkYXRlIGV2ZXJ5dGhpbmc6IGVhY2ggc2NoZW1hIG11c3RcbiAgICogQHBhcmFtIGRhdGEgSlNPTiBkYXRhIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBzY2hlbWEgU3Vic2V0IG9mIEpTT04gU2NoZW1hLiBNdXN0IGhhdmUgYSBgdHlwZWAuXG4gICAqIEByZXR1cm5zIElmIGRhdGEgaXMgdmFsaWQ6IGB0cnVlYCwgaWYgaXQgaXMgaW52YWxpZDogYGZhbHNlYFxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFzdGVyL2RvY3MvVkFMSURBVElPTi5tZH1cbiAgICovXG4gIHZhbGlkYXRlKGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYSk6IGJvb2xlYW4ge1xuXG4gICAgc3dpdGNoIChzY2hlbWEudHlwZSkge1xuXG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVN0cmluZyhkYXRhLCBzY2hlbWEpO1xuICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIGNhc2UgJ2ludGVnZXInOlxuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZU51bWJlcihkYXRhLCBzY2hlbWEpO1xuICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQm9vbGVhbihkYXRhLCBzY2hlbWEpO1xuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUFycmF5KGRhdGEsIHNjaGVtYSk7XG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZU9iamVjdChkYXRhLCBzY2hlbWEpO1xuXG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYSBzdHJpbmdcbiAgICogQHBhcmFtIGRhdGEgRGF0YSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0gc2NoZW1hIFNjaGVtYSBkZXNjcmliaW5nIHRoZSBzdHJpbmdcbiAgICogQHJldHVybnMgSWYgZGF0YSBpcyB2YWxpZDogYHRydWVgLCBpZiBpdCBpcyBpbnZhbGlkOiBgZmFsc2VgXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVTdHJpbmcoZGF0YTogdW5rbm93biwgc2NoZW1hOiBKU09OU2NoZW1hU3RyaW5nKTogYm9vbGVhbiB7XG5cbiAgICBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnZhbGlkYXRlQ29uc3QoZGF0YSwgc2NoZW1hKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghdGhpcy52YWxpZGF0ZUVudW0oZGF0YSwgc2NoZW1hKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICgoc2NoZW1hLm1heExlbmd0aCAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YS5sZW5ndGggPiBzY2hlbWEubWF4TGVuZ3RoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICgoc2NoZW1hLm1pbkxlbmd0aCAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YS5sZW5ndGggPCBzY2hlbWEubWluTGVuZ3RoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWEucGF0dGVybikge1xuXG4gICAgICBsZXQgcmVndWxhckV4cHJlc3Npb246IFJlZ0V4cCB8IG51bGwgPSBudWxsO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZWd1bGFyRXhwcmVzc2lvbiA9IG5ldyBSZWdFeHAoc2NoZW1hLnBhdHRlcm4pO1xuICAgICAgfSBjYXRjaCB7fVxuXG4gICAgICBpZiAocmVndWxhckV4cHJlc3Npb24gJiYgIXJlZ3VsYXJFeHByZXNzaW9uLnRlc3QoZGF0YSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIG51bWJlciBvciBhbiBpbnRlZ2VyXG4gICAqIEBwYXJhbSBkYXRhIERhdGEgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHNjaGVtYSBTY2hlbWEgZGVzY3JpYmluZyB0aGUgbnVtYmVyIG9yIGludGVnZXJcbiAgICogQHJldHVybnMgSWYgZGF0YSBpcyB2YWxpZDogYHRydWVgLCBpZiBpdCBpcyBpbnZhbGlkOiBgZmFsc2VgXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVOdW1iZXIoZGF0YTogdW5rbm93biwgc2NoZW1hOiBKU09OU2NoZW1hTnVtYmVyIHzCoEpTT05TY2hlbWFJbnRlZ2VyKTogYm9vbGVhbiB7XG5cbiAgICBpZiAodHlwZW9mIGRhdGEgIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKChzY2hlbWEudHlwZSA9PT0gJ2ludGVnZXInKSAmJiAhTnVtYmVyLmlzSW50ZWdlcihkYXRhKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghdGhpcy52YWxpZGF0ZUNvbnN0KGRhdGEsIHNjaGVtYSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMudmFsaWRhdGVFbnVtKGRhdGEsIHNjaGVtYSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKiBUZXN0IGlzIGRvbmUgdGhpcyB3YXkgdG8gbm90IGRpdmlkZSBieSAwICovXG4gICAgaWYgKHNjaGVtYS5tdWx0aXBsZU9mICYmICFOdW1iZXIuaXNJbnRlZ2VyKGRhdGEgLyBzY2hlbWEubXVsdGlwbGVPZikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoKHNjaGVtYS5tYXhpbXVtICE9PSB1bmRlZmluZWQpICYmIChkYXRhID4gc2NoZW1hLm1heGltdW0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoKHNjaGVtYS5leGNsdXNpdmVNYXhpbXVtICE9PSB1bmRlZmluZWQpICYmIChkYXRhID49IHNjaGVtYS5leGNsdXNpdmVNYXhpbXVtKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgfVxuXG4gICAgaWYgKChzY2hlbWEubWluaW11bSAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YSA8IHNjaGVtYS5taW5pbXVtKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgfVxuXG4gICAgaWYgKChzY2hlbWEuZXhjbHVzaXZlTWluaW11bSAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YSA8PSBzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuXG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYSBib29sZWFuXG4gICAqIEBwYXJhbSBkYXRhIERhdGEgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHNjaGVtYSBTY2hlbWEgZGVzY3JpYmluZyB0aGUgYm9vbGVhblxuICAgKiBAcmV0dXJucyBJZiBkYXRhIGlzIHZhbGlkOiBgdHJ1ZWAsIGlmIGl0IGlzIGludmFsaWQ6IGBmYWxzZWBcbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZUJvb2xlYW4oZGF0YTogdW5rbm93biwgc2NoZW1hOiBKU09OU2NoZW1hQm9vbGVhbik6IGJvb2xlYW4ge1xuXG4gICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMudmFsaWRhdGVDb25zdChkYXRhLCBzY2hlbWEpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbiBhcnJheVxuICAgKiBAcGFyYW0gZGF0YSBEYXRhIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBzY2hlbWEgU2NoZW1hIGRlc2NyaWJpbmcgdGhlIGFycmF5XG4gICAqIEByZXR1cm5zIElmIGRhdGEgaXMgdmFsaWQ6IGB0cnVlYCwgaWYgaXQgaXMgaW52YWxpZDogYGZhbHNlYFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlQXJyYXkoZGF0YTogdW5rbm93biwgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXkpOiBib29sZWFuIHtcblxuICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICgoc2NoZW1hLm1heEl0ZW1zICE9PSB1bmRlZmluZWQpICYmIChkYXRhLmxlbmd0aCA+IHNjaGVtYS5tYXhJdGVtcykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoKHNjaGVtYS5taW5JdGVtcyAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YS5sZW5ndGggPCBzY2hlbWEubWluSXRlbXMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYS51bmlxdWVJdGVtcykge1xuXG4gICAgICAvKiBDcmVhdGUgYSBzZXQgdG8gZWxpbWluYXRlIHZhbHVlcyB3aXRoIG11bHRpcGxlIG9jY3VyZW5jZXMgKi9cbiAgICAgIGNvbnN0IGRhdGFTZXQgPSBuZXcgU2V0KGRhdGEpO1xuXG4gICAgICBpZiAoZGF0YS5sZW5ndGggIT09IGRhdGFTZXQuc2l6ZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICAvKiBTcGVjaWZpYyB0ZXN0IGZvciB0dXBsZXMgKi9cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzY2hlbWEuaXRlbXMpKSB7XG5cbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlVHVwbGUoZGF0YSwgc2NoZW1hLml0ZW1zKTtcblxuICAgIH1cblxuICAgIC8qIFZhbGlkYXRlIGFsbCB0aGUgdmFsdWVzIGluIGFycmF5ICovXG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiBkYXRhKSB7XG5cbiAgICAgIGlmICghdGhpcy52YWxpZGF0ZSh2YWx1ZSwgc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGEgdHVwbGUgKGFycmF5IHdpdGggZml4ZWQgbGVuZ3RoIGFuZCBtdWx0aXBsZSB0eXBlcylcbiAgICogQHBhcmFtIGRhdGEgRGF0YSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0gc2NoZW1hcyBTY2hlbWFzIGRlc2NyaWJpbmcgdGhlIHR1cGxlXG4gICAqIEByZXR1cm5zIElmIGRhdGEgaXMgdmFsaWQ6IGB0cnVlYCwgaWYgaXQgaXMgaW52YWxpZDogYGZhbHNlYFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlVHVwbGUoZGF0YTogdW5rbm93bltdLCBzY2hlbWFzOiBKU09OU2NoZW1hW10pOiBib29sZWFuIHtcblxuICAgIC8qIFR1cGxlcyBoYXZlIGEgZml4ZWQgbGVuZ3RoICovXG4gICAgaWYgKGRhdGEubGVuZ3RoICE9PSBzY2hlbWFzLmxlbmd0aCkge1xuXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNjaGVtYXMubGVuZ3RoOyBpICs9IDEpIHtcblxuICAgICAgaWYgKCF0aGlzLnZhbGlkYXRlKGRhdGFbaV0sIHNjaGVtYXNbaV0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuXG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYW4gb2JqZWN0XG4gICAqIEBwYXJhbSBkYXRhIERhdGEgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHNjaGVtYSBKU09OIHNjaGVtYSBkZXNjcmliaW5nIHRoZSBvYmplY3RcbiAgICogQHJldHVybnMgSWYgZGF0YSBpcyB2YWxpZDogYHRydWVgLCBpZiBpdCBpcyBpbnZhbGlkOiBgZmFsc2VgXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVPYmplY3QoZGF0YTogdW5rbm93biwgc2NoZW1hOiBKU09OU2NoZW1hT2JqZWN0KTogYm9vbGVhbiB7XG5cbiAgICAvKiBDaGVjayB0aGUgdHlwZSBhbmQgaWYgbm90IGBudWxsYCBhcyBgbnVsbGAgYWxzbyBoYXZlIHRoZSB0eXBlIGBvYmplY3RgIGluIG9sZCBicm93c2VycyAqL1xuICAgIGlmICgodHlwZW9mIGRhdGEgIT09ICdvYmplY3QnKSB8fCAoZGF0YSA9PT0gbnVsbCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKiBDaGVjayBpZiB0aGUgb2JqZWN0IGRvZXNuJ3QgaGF2ZSBtb3JlIHByb3BlcnRpZXMgdGhhbiBleHBlY3RlZFxuICAgICAqIEVxdWl2YWxlbnQgb2YgYGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZWBcbiAgICAgKi9cbiAgICBpZiAoT2JqZWN0LmtleXMoc2NoZW1hLnByb3BlcnRpZXMpLmxlbmd0aCA8IE9iamVjdC5rZXlzKGRhdGEpLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qIFZhbGlkYXRlIHJlcXVpcmVkIHByb3BlcnRpZXMgKi9cbiAgICBpZiAoc2NoZW1hLnJlcXVpcmVkKSB7XG5cbiAgICAgIGZvciAoY29uc3QgcmVxdWlyZWRQcm9wIG9mIHNjaGVtYS5yZXF1aXJlZCkge1xuXG4gICAgICAgIGlmICghZGF0YS5oYXNPd25Qcm9wZXJ0eShyZXF1aXJlZFByb3ApKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgIH1cblxuICAgIH1cblxuICAgIC8qIFJlY3Vyc2l2ZWx5IHZhbGlkYXRlIGFsbCBwcm9wZXJ0aWVzICovXG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBzY2hlbWEucHJvcGVydGllcykge1xuXG4gICAgICAvKiBGaWx0ZXIgdG8ga2VlcCBvbmx5IHJlYWwgcHJvcGVydGllcyAobm8gaW50ZXJuYWwgSlMgc3R1ZmYpIGFuZCBjaGVjayBpZiB0aGUgZGF0YSBoYXMgdGhlIHByb3BlcnR5IHRvbyAqL1xuICAgICAgaWYgKHNjaGVtYS5wcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KHByb3BlcnR5KSAmJiBkYXRhLmhhc093blByb3BlcnR5KHByb3BlcnR5KSkge1xuXG4gICAgICAgIGlmICghdGhpcy52YWxpZGF0ZSgoZGF0YSBhcyB7IFtrOiBzdHJpbmddOiB1bmtub3duOyB9KVtwcm9wZXJ0eV0sIHNjaGVtYS5wcm9wZXJ0aWVzW3Byb3BlcnR5XSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgfVxuXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIGNvbnN0YW50XG4gICAqIEBwYXJhbSBkYXRhIERhdGEgdGEgdmFsaWRhdGVcbiAgICogQHBhcmFtIHNjaGVtYSBKU09OIHNjaGVtYSBkZXNjcmliaW5nIHRoZSBjb25zdGFudFxuICAgKiBAcmV0dXJucyBJZiBkYXRhIGlzIHZhbGlkOiBgdHJ1ZWAsIGlmIGl0IGlzIGludmFsaWQ6IGBmYWxzZWBcbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZUNvbnN0KGRhdGE6IHVua25vd24sIHNjaGVtYTogSlNPTlNjaGVtYUJvb2xlYW4gfCBKU09OU2NoZW1hSW50ZWdlciB8IEpTT05TY2hlbWFOdW1iZXIgfCBKU09OU2NoZW1hU3RyaW5nKTogYm9vbGVhbiB7XG5cbiAgICBpZiAoIXNjaGVtYS5jb25zdCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIChkYXRhID09PSBzY2hlbWEuY29uc3QpO1xuXG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYW4gZW51bVxuICAgKiBAcGFyYW0gZGF0YSBEYXRhIHRhIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBzY2hlbWEgSlNPTiBzY2hlbWEgZGVzY3JpYmluZyB0aGUgZW51bVxuICAgKiBAcmV0dXJucyBJZiBkYXRhIGlzIHZhbGlkOiBgdHJ1ZWAsIGlmIGl0IGlzIGludmFsaWQ6IGBmYWxzZWBcbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZUVudW0oZGF0YTogdW5rbm93biwgc2NoZW1hOiBKU09OU2NoZW1hSW50ZWdlciB8IEpTT05TY2hlbWFOdW1iZXIgfCBKU09OU2NoZW1hU3RyaW5nKTogYm9vbGVhbiB7XG5cbiAgICBpZiAoIXNjaGVtYS5lbnVtKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKiBDYXN0IGFzIHRoZSBkYXRhIGNhbiBiZSBvZiBtdWx0aXBsZSB0eXBlcywgYW5kIHNvIFR5cGVTY3JpcHQgaXMgbG9zdCAqL1xuICAgIHJldHVybiAoKHNjaGVtYS5lbnVtIGFzIHVua25vd25bXSkuaW5jbHVkZXMoZGF0YSkpO1xuXG4gIH1cblxufVxuIl19

@@ -8,233 +8,236 @@ import { __decorate, __param } from 'tslib';

// TODO: detailed error messages?
let JSONValidator = class JSONValidator {
/**
* Validate a JSON data against a Jsubset of the JSON Schema standard.
* Types are enforced to validate everything: each schema must
* @param data JSON data to validate
* @param schema Subset of JSON Schema. Must have a `type`.
* @returns If data is valid: `true`, if it is invalid: `false`
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/VALIDATION.md}
*/
validate(data, schema) {
switch (schema.type) {
case 'string':
return this.validateString(data, schema);
case 'number':
case 'integer':
return this.validateNumber(data, schema);
case 'boolean':
return this.validateBoolean(data, schema);
case 'array':
return this.validateArray(data, schema);
case 'object':
return this.validateObject(data, schema);
let JSONValidator = /** @class */ (() => {
let JSONValidator = class JSONValidator {
/**
* Validate a JSON data against a Jsubset of the JSON Schema standard.
* Types are enforced to validate everything: each schema must
* @param data JSON data to validate
* @param schema Subset of JSON Schema. Must have a `type`.
* @returns If data is valid: `true`, if it is invalid: `false`
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/VALIDATION.md}
*/
validate(data, schema) {
switch (schema.type) {
case 'string':
return this.validateString(data, schema);
case 'number':
case 'integer':
return this.validateNumber(data, schema);
case 'boolean':
return this.validateBoolean(data, schema);
case 'array':
return this.validateArray(data, schema);
case 'object':
return this.validateObject(data, schema);
}
}
}
/**
* Validate a string
* @param data Data to validate
* @param schema Schema describing the string
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateString(data, schema) {
if (typeof data !== 'string') {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
if (!this.validateEnum(data, schema)) {
return false;
}
if ((schema.maxLength !== undefined) && (data.length > schema.maxLength)) {
return false;
}
if ((schema.minLength !== undefined) && (data.length < schema.minLength)) {
return false;
}
if (schema.pattern) {
let regularExpression = null;
try {
regularExpression = new RegExp(schema.pattern);
/**
* Validate a string
* @param data Data to validate
* @param schema Schema describing the string
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateString(data, schema) {
if (typeof data !== 'string') {
return false;
}
catch (_a) { }
if (regularExpression && !regularExpression.test(data)) {
if (!this.validateConst(data, schema)) {
return false;
}
}
return true;
}
/**
* Validate a number or an integer
* @param data Data to validate
* @param schema Schema describing the number or integer
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateNumber(data, schema) {
if (typeof data !== 'number') {
return false;
}
if ((schema.type === 'integer') && !Number.isInteger(data)) {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
if (!this.validateEnum(data, schema)) {
return false;
}
/* Test is done this way to not divide by 0 */
if (schema.multipleOf && !Number.isInteger(data / schema.multipleOf)) {
return false;
}
if ((schema.maximum !== undefined) && (data > schema.maximum)) {
return false;
}
if ((schema.exclusiveMaximum !== undefined) && (data >= schema.exclusiveMaximum)) {
return false;
}
if ((schema.minimum !== undefined) && (data < schema.minimum)) {
return false;
}
if ((schema.exclusiveMinimum !== undefined) && (data <= schema.exclusiveMinimum)) {
return false;
}
return true;
}
/**
* Validate a boolean
* @param data Data to validate
* @param schema Schema describing the boolean
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateBoolean(data, schema) {
if (typeof data !== 'boolean') {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
return true;
}
/**
* Validate an array
* @param data Data to validate
* @param schema Schema describing the array
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateArray(data, schema) {
if (!Array.isArray(data)) {
return false;
}
if ((schema.maxItems !== undefined) && (data.length > schema.maxItems)) {
return false;
}
if ((schema.minItems !== undefined) && (data.length < schema.minItems)) {
return false;
}
if (schema.uniqueItems) {
/* Create a set to eliminate values with multiple occurences */
const dataSet = new Set(data);
if (data.length !== dataSet.size) {
if (!this.validateEnum(data, schema)) {
return false;
}
if ((schema.maxLength !== undefined) && (data.length > schema.maxLength)) {
return false;
}
if ((schema.minLength !== undefined) && (data.length < schema.minLength)) {
return false;
}
if (schema.pattern) {
let regularExpression = null;
try {
regularExpression = new RegExp(schema.pattern);
}
catch (_a) { }
if (regularExpression && !regularExpression.test(data)) {
return false;
}
}
return true;
}
/* Specific test for tuples */
if (Array.isArray(schema.items)) {
return this.validateTuple(data, schema.items);
}
/* Validate all the values in array */
for (const value of data) {
if (!this.validate(value, schema.items)) {
/**
* Validate a number or an integer
* @param data Data to validate
* @param schema Schema describing the number or integer
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateNumber(data, schema) {
if (typeof data !== 'number') {
return false;
}
if ((schema.type === 'integer') && !Number.isInteger(data)) {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
if (!this.validateEnum(data, schema)) {
return false;
}
/* Test is done this way to not divide by 0 */
if (schema.multipleOf && !Number.isInteger(data / schema.multipleOf)) {
return false;
}
if ((schema.maximum !== undefined) && (data > schema.maximum)) {
return false;
}
if ((schema.exclusiveMaximum !== undefined) && (data >= schema.exclusiveMaximum)) {
return false;
}
if ((schema.minimum !== undefined) && (data < schema.minimum)) {
return false;
}
if ((schema.exclusiveMinimum !== undefined) && (data <= schema.exclusiveMinimum)) {
return false;
}
return true;
}
return true;
}
/**
* Validate a tuple (array with fixed length and multiple types)
* @param data Data to validate
* @param schemas Schemas describing the tuple
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateTuple(data, schemas) {
/* Tuples have a fixed length */
if (data.length !== schemas.length) {
return false;
}
for (let i = 0; i < schemas.length; i += 1) {
if (!this.validate(data[i], schemas[i])) {
/**
* Validate a boolean
* @param data Data to validate
* @param schema Schema describing the boolean
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateBoolean(data, schema) {
if (typeof data !== 'boolean') {
return false;
}
if (!this.validateConst(data, schema)) {
return false;
}
return true;
}
return true;
}
/**
* Validate an object
* @param data Data to validate
* @param schema JSON schema describing the object
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateObject(data, schema) {
/* Check the type and if not `null` as `null` also have the type `object` in old browsers */
if ((typeof data !== 'object') || (data === null)) {
return false;
}
/* Check if the object doesn't have more properties than expected
* Equivalent of `additionalProperties: false`
/**
* Validate an array
* @param data Data to validate
* @param schema Schema describing the array
* @returns If data is valid: `true`, if it is invalid: `false`
*/
if (Object.keys(schema.properties).length < Object.keys(data).length) {
return false;
}
/* Validate required properties */
if (schema.required) {
for (const requiredProp of schema.required) {
if (!data.hasOwnProperty(requiredProp)) {
validateArray(data, schema) {
if (!Array.isArray(data)) {
return false;
}
if ((schema.maxItems !== undefined) && (data.length > schema.maxItems)) {
return false;
}
if ((schema.minItems !== undefined) && (data.length < schema.minItems)) {
return false;
}
if (schema.uniqueItems) {
/* Create a set to eliminate values with multiple occurences */
const dataSet = new Set(data);
if (data.length !== dataSet.size) {
return false;
}
}
/* Specific test for tuples */
if (Array.isArray(schema.items)) {
return this.validateTuple(data, schema.items);
}
/* Validate all the values in array */
for (const value of data) {
if (!this.validate(value, schema.items)) {
return false;
}
}
return true;
}
/* Recursively validate all properties */
for (const property in schema.properties) {
/* Filter to keep only real properties (no internal JS stuff) and check if the data has the property too */
if (schema.properties.hasOwnProperty(property) && data.hasOwnProperty(property)) {
if (!this.validate(data[property], schema.properties[property])) {
/**
* Validate a tuple (array with fixed length and multiple types)
* @param data Data to validate
* @param schemas Schemas describing the tuple
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateTuple(data, schemas) {
/* Tuples have a fixed length */
if (data.length !== schemas.length) {
return false;
}
for (let i = 0; i < schemas.length; i += 1) {
if (!this.validate(data[i], schemas[i])) {
return false;
}
}
}
return true;
}
/**
* Validate a constant
* @param data Data ta validate
* @param schema JSON schema describing the constant
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateConst(data, schema) {
if (!schema.const) {
return true;
}
return (data === schema.const);
}
/**
* Validate an enum
* @param data Data ta validate
* @param schema JSON schema describing the enum
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateEnum(data, schema) {
if (!schema.enum) {
/**
* Validate an object
* @param data Data to validate
* @param schema JSON schema describing the object
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateObject(data, schema) {
/* Check the type and if not `null` as `null` also have the type `object` in old browsers */
if ((typeof data !== 'object') || (data === null)) {
return false;
}
/* Check if the object doesn't have more properties than expected
* Equivalent of `additionalProperties: false`
*/
if (Object.keys(schema.properties).length < Object.keys(data).length) {
return false;
}
/* Validate required properties */
if (schema.required) {
for (const requiredProp of schema.required) {
if (!data.hasOwnProperty(requiredProp)) {
return false;
}
}
}
/* Recursively validate all properties */
for (const property in schema.properties) {
/* Filter to keep only real properties (no internal JS stuff) and check if the data has the property too */
if (schema.properties.hasOwnProperty(property) && data.hasOwnProperty(property)) {
if (!this.validate(data[property], schema.properties[property])) {
return false;
}
}
}
return true;
}
/* Cast as the data can be of multiple types, and so TypeScript is lost */
return (schema.enum.includes(data));
}
};
JSONValidator.ɵprov = ɵɵdefineInjectable({ factory: function JSONValidator_Factory() { return new JSONValidator(); }, token: JSONValidator, providedIn: "root" });
JSONValidator = __decorate([
Injectable({
providedIn: 'root'
})
], JSONValidator);
/**
* Validate a constant
* @param data Data ta validate
* @param schema JSON schema describing the constant
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateConst(data, schema) {
if (!schema.const) {
return true;
}
return (data === schema.const);
}
/**
* Validate an enum
* @param data Data ta validate
* @param schema JSON schema describing the enum
* @returns If data is valid: `true`, if it is invalid: `false`
*/
validateEnum(data, schema) {
if (!schema.enum) {
return true;
}
/* Cast as the data can be of multiple types, and so TypeScript is lost */
return (schema.enum.includes(data));
}
};
JSONValidator.ɵprov = ɵɵdefineInjectable({ factory: function JSONValidator_Factory() { return new JSONValidator(); }, token: JSONValidator, providedIn: "root" });
JSONValidator = __decorate([
Injectable({
providedIn: 'root'
})
], JSONValidator);
return JSONValidator;
})();

@@ -327,345 +330,381 @@ /**

let IndexedDBDatabase = class IndexedDBDatabase {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param dbName `indexedDB` database name
* @param storeName `indexedDB` store name
* @param dbVersion `indexedDB` database version
* @param noWrap Flag to not wrap `indexedDB` values for interoperability or to wrap for backward compatibility
*/
constructor(dbName = DEFAULT_IDB_DB_NAME, storeName = DEFAULT_IDB_STORE_NAME, dbVersion = DEFAULT_IDB_DB_VERSION, noWrap = DEFAULT_IDB_NO_WRAP) {
let IndexedDBDatabase = /** @class */ (() => {
let IndexedDBDatabase = class IndexedDBDatabase {
/**
* `indexedDB` database connection, wrapped in a RxJS `ReplaySubject` to be able to access the connection
* even after the connection success event happened
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param dbName `indexedDB` database name
* @param storeName `indexedDB` store name
* @param dbVersion `indexedDB` database version
* @param noWrap Flag to not wrap `indexedDB` values for interoperability or to wrap for backward compatibility
*/
this.database = new ReplaySubject(1);
constructor(dbName = DEFAULT_IDB_DB_NAME, storeName = DEFAULT_IDB_STORE_NAME, dbVersion = DEFAULT_IDB_DB_VERSION, noWrap = DEFAULT_IDB_NO_WRAP) {
/**
* `indexedDB` database connection, wrapped in a RxJS `ReplaySubject` to be able to access the connection
* even after the connection success event happened
*/
this.database = new ReplaySubject(1);
/**
* Index used when wrapping value. *For backward compatibility only.*
*/
this.wrapIndex = 'value';
this.dbName = dbName;
this.storeName = storeName;
this.dbVersion = dbVersion;
this.noWrap = noWrap;
/* Connect to `indexedDB`, with prefix if provided by the user */
this.connect();
}
/**
* Index used when wrapping value. *For backward compatibility only.*
* Information about `indexedDB` connection. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version
*/
this.wrapIndex = 'value';
this.dbName = dbName;
this.storeName = storeName;
this.dbVersion = dbVersion;
this.noWrap = noWrap;
/* Connect to `indexedDB`, with prefix if provided by the user */
this.connect();
}
/**
* Information about `indexedDB` connection. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version
*/
get backingStore() {
return {
database: this.dbName,
store: this.storeName,
version: this.dbVersion,
};
}
/**
* Number of items in our `indexedDB` database and object store
*/
get size() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request to know the number of items */
const request = store.count();
/* Return the result */
return events.pipe(map(() => request.result));
}),
/* The observable will complete after the first value */
first());
}
/**
* Gets an item value in our `indexedDB` store
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in an RxJS `Observable`
*/
get(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request the value with the key provided by the user */
const request = store.get(key);
/* Listen events and return the result */
return events.pipe(map(() => {
if ((request.result !== undefined) && (request.result !== null)) {
/* Prior to v8, the value was wrapped in an `{ value: ...}` object */
if (!this.noWrap && (typeof request.result === 'object') && (this.wrapIndex in request.result) &&
(request.result[this.wrapIndex] !== undefined) && (request.result[this.wrapIndex] !== null)) {
return request.result[this.wrapIndex];
get backingStore() {
return {
database: this.dbName,
store: this.storeName,
version: this.dbVersion,
};
}
/**
* Number of items in our `indexedDB` database and object store
*/
get size() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request to know the number of items */
const request = store.count();
/* Return the result */
return events.pipe(map(() => request.result));
}),
/* The observable will complete after the first value */
first());
}
/**
* Gets an item value in our `indexedDB` store
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in an RxJS `Observable`
*/
get(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Request the value with the key provided by the user */
const request = store.get(key);
/* Listen events and return the result */
return events.pipe(map(() => {
if ((request.result !== undefined) && (request.result !== null)) {
/* Prior to v8, the value was wrapped in an `{ value: ...}` object */
if (!this.noWrap && (typeof request.result === 'object') && (this.wrapIndex in request.result) &&
(request.result[this.wrapIndex] !== undefined) && (request.result[this.wrapIndex] !== null)) {
return request.result[this.wrapIndex];
}
else {
/* Cast to the wanted type */
return request.result;
}
}
else {
/* Cast to the wanted type */
return request.result;
/* Return `undefined` if the value is empty */
return undefined;
}));
}),
/* The observable will complete after the first value */
first());
}
/**
* Sets an item in our `indexedDB` store
* @param key The item's key
* @param data The item's value
* @returns An RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
/* Storing `undefined` in `indexedDb` can cause issues in some browsers so removing item instead */
if (data === undefined) {
return this.delete(key);
}
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Prior to v8, data was wrapped in a `{ value: ... }` object */
const dataToStore = this.noWrap ? data : { [this.wrapIndex]: data };
/* Add if the item is not existing yet, or update otherwise */
store.put(dataToStore, key);
/* Listen to events and return `undefined` as no value is expected */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
/**
* Deletes an item in our `indexedDB` store
* @param key The item's key
* @returns An RxJS `Observable` to wait the end of the operation
*/
delete(key) {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete the item in store */
store.delete(key);
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
/**
* Deletes all items from our `indexedDB` objet store
* @returns An RxJS `Observable` to wait the end of the operation
*/
clear() {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete all items in object store */
store.clear();
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete */
first());
}
/**
* Get all the keys in our `indexedDB` store
* @returns An RxJS `Observable` iterating on each key
*/
keys() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(
/* `first()` is used as the final operator in other methods to complete the `Observable`
* (as it all starts from a `ReplaySubject` which never ends),
* but as this method is iterating over multiple values, `first()` **must** be used here */
first(), mergeMap((transactionData) => {
const { store } = transactionData;
/* Open a cursor on the store
* `.openKeyCursor()` is better for performance, but only available in indexedDB v2 (missing in IE/Edge)
* Avoid issues like https://github.com/cyrilletuzi/angular-async-local-storage/issues/69 */
const request = ('openKeyCursor' in store) ? store.openKeyCursor() : store.openCursor();
/* Listen to success event */
const success$ = fromEvent(request, 'success').pipe(
/* Stop the `Observable` when the cursor is `null` */
takeWhile(() => (request.result !== null)),
/* This lib only allows string keys, but user could have added other types of keys from outside
* It's OK to cast as the cursor as been tested in the previous operator */
map(() => request.result.key.toString()),
/* Iterate on the cursor */
tap(() => { request.result.continue(); }));
/* Listen to error event and if so, throw an error */
const error$ = this.listenError(request);
/* Choose the first event to occur */
return race([success$, error$]);
}));
}
/**
* Check if a key exists in our `indexedDB` store
* @returns An RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Check if the key exists in the store
* `getKey()` is better but only available in `indexedDB` v2 (Chrome >= 58, missing in IE/Edge).
* In older browsers, the value is checked instead, but it could lead to an exception
* if `undefined` was stored outside of this lib (e.g. directly with the native `indexedDB` API).
* Fixes https://github.com/cyrilletuzi/angular-async-local-storage/issues/69
*/
const request = ('getKey' in store) ? store.getKey(key) : store.get(key);
/* Listen to events and return `true` or `false` */
return events.pipe(map(() => (request.result !== undefined) ? true : false));
}),
/* The observable will complete */
first());
}
/**
* Connects to `indexedDB` and creates the object store on first time
*/
connect() {
let request;
/* Connect to `indexedDB`
* Will fail in Safari cross-origin iframes
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/42} */
try {
/* Do NOT explicit `window` here, as `indexedDB` could be used from a web worker too */
request = indexedDB.open(this.dbName, this.dbVersion);
}
catch (_a) {
this.database.error(new IDBBrokenError());
return;
}
/* Create store on first connection */
this.createStore(request);
/* Listen to success and error events */
const success$ = fromEvent(request, 'success');
const error$ = this.listenError(request);
/* Choose the first to occur */
race([success$, error$])
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Register the database connection in the `ReplaySubject` for further access */
this.database.next(request.result);
},
error: () => {
/* Firefox private mode issue: fallback storage if IndexedDb connection is failing
* @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=781982}
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/26} */
this.database.error(new IDBBrokenError());
},
});
}
/**
* Create store on first use of `indexedDB`
* @param request `indexedDB` database opening request
*/
createStore(request) {
/* Listen to the event fired on first connection */
fromEvent(request, 'upgradeneeded')
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Check if the store already exists, to avoid error */
if (!request.result.objectStoreNames.contains(this.storeName)) {
/* Create the object store */
request.result.createObjectStore(this.storeName);
}
}
/* Return `undefined` if the value is empty */
return undefined;
});
}
/**
* Open an `indexedDB` transaction and get our store
* @param mode `readonly` or `readwrite`
* @returns An `indexedDB` transaction store and events, wrapped in an RxJS `Observable`
*/
transaction(mode) {
/* From the `indexedDB` connection, open a transaction and get the store */
return this.database
.pipe(mergeMap((database) => {
let transaction;
try {
transaction = database.transaction([this.storeName], mode);
}
catch (error) {
/* The store could have been deleted from outside */
return throwError(error);
}
/* Get the store from the transaction */
const store = transaction.objectStore(this.storeName);
/* Listen transaction `complete` and `error` events */
const events = this.listenTransactionEvents(transaction);
return of({ store, events });
}));
}),
/* The observable will complete after the first value */
first());
}
/**
* Sets an item in our `indexedDB` store
* @param key The item's key
* @param data The item's value
* @returns An RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
/* Storing `undefined` in `indexedDb` can cause issues in some browsers so removing item instead */
if (data === undefined) {
return this.delete(key);
}
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Prior to v8, data was wrapped in a `{ value: ... }` object */
const dataToStore = this.noWrap ? data : { [this.wrapIndex]: data };
/* Add if the item is not existing yet, or update otherwise */
store.put(dataToStore, key);
/* Listen to events and return `undefined` as no value is expected */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
/**
* Deletes an item in our `indexedDB` store
* @param key The item's key
* @returns An RxJS `Observable` to wait the end of the operation
*/
delete(key) {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete the item in store */
store.delete(key);
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete after the first value */
first());
}
/**
* Deletes all items from our `indexedDB` objet store
* @returns An RxJS `Observable` to wait the end of the operation
*/
clear() {
/* Open a transaction in write mode */
return this.transaction('readwrite').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Delete all items in object store */
store.clear();
/* Listen to events and return `undefined` as no data is expected here */
return events.pipe(mapTo(undefined));
}),
/* The observable will complete */
first());
}
/**
* Get all the keys in our `indexedDB` store
* @returns An RxJS `Observable` iterating on each key
*/
keys() {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(
/* `first()` is used as the final operator in other methods to complete the `Observable`
* (as it all starts from a `ReplaySubject` which never ends),
* but as this method is iterating over multiple values, `first()` **must** be used here */
first(), mergeMap((transactionData) => {
const { store } = transactionData;
/* Open a cursor on the store
* `.openKeyCursor()` is better for performance, but only available in indexedDB v2 (missing in IE/Edge)
* Avoid issues like https://github.com/cyrilletuzi/angular-async-local-storage/issues/69 */
const request = ('openKeyCursor' in store) ? store.openKeyCursor() : store.openCursor();
/* Listen to success event */
const success$ = fromEvent(request, 'success').pipe(
/* Stop the `Observable` when the cursor is `null` */
takeWhile(() => (request.result !== null)),
/* This lib only allows string keys, but user could have added other types of keys from outside
* It's OK to cast as the cursor as been tested in the previous operator */
map(() => request.result.key.toString()),
/* Iterate on the cursor */
tap(() => { request.result.continue(); }));
/* Listen to error event and if so, throw an error */
const error$ = this.listenError(request);
/**
* Listen errors on a transaction or request, and throw if trigerred
* @param transactionOrRequest `indexedDb` transaction or request to listen
* @returns An `Observable` listening to errors
*/
listenError(transactionOrRequest) {
return fromEvent(transactionOrRequest, 'error').pipe(
/* Throw on error to be able to catch errors in RxJS way */
mergeMap(() => throwError(transactionOrRequest.error)));
}
/**
* Listen transaction `complete` and `error` events
* @param transaction Transaction to listen
* @returns An `Observable` listening to transaction `complete` and `error` events
*/
listenTransactionEvents(transaction) {
/* Listen to the `complete` event */
const complete$ = fromEvent(transaction, 'complete');
/* Listen to the `error` event */
const error$ = this.listenError(transaction);
/* Choose the first event to occur */
return race([success$, error$]);
}));
}
/**
* Check if a key exists in our `indexedDB` store
* @returns An RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Open a transaction in read-only mode */
return this.transaction('readonly').pipe(mergeMap((transactionData) => {
const { store, events } = transactionData;
/* Check if the key exists in the store
* `getKey()` is better but only available in `indexedDB` v2 (Chrome >= 58, missing in IE/Edge).
* In older browsers, the value is checked instead, but it could lead to an exception
* if `undefined` was stored outside of this lib (e.g. directly with the native `indexedDB` API).
* Fixes https://github.com/cyrilletuzi/angular-async-local-storage/issues/69
*/
const request = ('getKey' in store) ? store.getKey(key) : store.get(key);
/* Listen to events and return `true` or `false` */
return events.pipe(map(() => (request.result !== undefined) ? true : false));
}),
/* The observable will complete */
first());
}
/**
* Connects to `indexedDB` and creates the object store on first time
*/
connect() {
let request;
/* Connect to `indexedDB`
* Will fail in Safari cross-origin iframes
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/42} */
try {
/* Do NOT explicit `window` here, as `indexedDB` could be used from a web worker too */
request = indexedDB.open(this.dbName, this.dbVersion);
return race([complete$, error$]);
}
catch (_a) {
this.database.error(new IDBBrokenError());
return;
};
IndexedDBDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_STORE_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_VERSION,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_NO_WRAP,] }] }
];
IndexedDBDatabase.ɵprov = ɵɵdefineInjectable({ factory: function IndexedDBDatabase_Factory() { return new IndexedDBDatabase(ɵɵinject(IDB_DB_NAME), ɵɵinject(IDB_STORE_NAME), ɵɵinject(IDB_DB_VERSION), ɵɵinject(IDB_NO_WRAP)); }, token: IndexedDBDatabase, providedIn: "root" });
IndexedDBDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(IDB_DB_NAME)),
__param(1, Inject(IDB_STORE_NAME)),
__param(2, Inject(IDB_DB_VERSION)),
__param(3, Inject(IDB_NO_WRAP))
], IndexedDBDatabase);
return IndexedDBDatabase;
})();
let LocalStorageDatabase = /** @class */ (() => {
let LocalStorageDatabase = class LocalStorageDatabase {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param prefix Prefix option to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(prefix = '') {
/* Prefix if asked, or no prefix otherwise */
this.prefix = prefix || '';
}
/* Create store on first connection */
this.createStore(request);
/* Listen to success and error events */
const success$ = fromEvent(request, 'success');
const error$ = this.listenError(request);
/* Choose the first to occur */
race([success$, error$])
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Register the database connection in the `ReplaySubject` for further access */
this.database.next(request.result);
},
error: () => {
/* Firefox private mode issue: fallback storage if IndexedDb connection is failing
* @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=781982}
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/issues/26} */
this.database.error(new IDBBrokenError());
},
});
}
/**
* Create store on first use of `indexedDB`
* @param request `indexedDB` database opening request
*/
createStore(request) {
/* Listen to the event fired on first connection */
fromEvent(request, 'upgradeneeded')
/* The observable will complete */
.pipe(first())
.subscribe({
next: () => {
/* Check if the store already exists, to avoid error */
if (!request.result.objectStoreNames.contains(this.storeName)) {
/* Create the object store */
request.result.createObjectStore(this.storeName);
/**
* Number of items in `localStorage`
*/
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(localStorage.length);
}
/**
* Gets an item value in `localStorage`
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
/* Get raw data */
const unparsedData = localStorage.getItem(this.prefixKey(key));
let parsedData;
/* No need to parse if data is `null` or `undefined` */
if ((unparsedData !== undefined) && (unparsedData !== null)) {
/* Try to parse */
try {
parsedData = JSON.parse(unparsedData);
}
catch (error) {
return throwError(error);
}
}
});
}
/**
* Open an `indexedDB` transaction and get our store
* @param mode `readonly` or `readwrite`
* @returns An `indexedDB` transaction store and events, wrapped in an RxJS `Observable`
*/
transaction(mode) {
/* From the `indexedDB` connection, open a transaction and get the store */
return this.database
.pipe(mergeMap((database) => {
let transaction;
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(parsedData);
}
/**
* Store an item in `localStorage`
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
let serializedData = null;
/* Check if data can be serialized */
const dataPrototype = Object.getPrototypeOf(data);
if ((typeof data === 'object') && (data !== null) && !Array.isArray(data) &&
!((dataPrototype === Object.prototype) || (dataPrototype === null))) {
return throwError(new SerializationError());
}
/* Try to stringify (can fail on circular references) */
try {
transaction = database.transaction([this.storeName], mode);
serializedData = JSON.stringify(data);
}
catch (error) {
/* The store could have been deleted from outside */
return throwError(error);
}
/* Get the store from the transaction */
const store = transaction.objectStore(this.storeName);
/* Listen transaction `complete` and `error` events */
const events = this.listenTransactionEvents(transaction);
return of({ store, events });
}));
}
/**
* Listen errors on a transaction or request, and throw if trigerred
* @param transactionOrRequest `indexedDb` transaction or request to listen
* @returns An `Observable` listening to errors
*/
listenError(transactionOrRequest) {
return fromEvent(transactionOrRequest, 'error').pipe(
/* Throw on error to be able to catch errors in RxJS way */
mergeMap(() => throwError(transactionOrRequest.error)));
}
/**
* Listen transaction `complete` and `error` events
* @param transaction Transaction to listen
* @returns An `Observable` listening to transaction `complete` and `error` events
*/
listenTransactionEvents(transaction) {
/* Listen to the `complete` event */
const complete$ = fromEvent(transaction, 'complete');
/* Listen to the `error` event */
const error$ = this.listenError(transaction);
/* Choose the first event to occur */
return race([complete$, error$]);
}
};
IndexedDBDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_STORE_NAME,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_DB_VERSION,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [IDB_NO_WRAP,] }] }
];
IndexedDBDatabase.ɵprov = ɵɵdefineInjectable({ factory: function IndexedDBDatabase_Factory() { return new IndexedDBDatabase(ɵɵinject(IDB_DB_NAME), ɵɵinject(IDB_STORE_NAME), ɵɵinject(IDB_DB_VERSION), ɵɵinject(IDB_NO_WRAP)); }, token: IndexedDBDatabase, providedIn: "root" });
IndexedDBDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(IDB_DB_NAME)),
__param(1, Inject(IDB_STORE_NAME)),
__param(2, Inject(IDB_DB_VERSION)),
__param(3, Inject(IDB_NO_WRAP))
], IndexedDBDatabase);
let LocalStorageDatabase = class LocalStorageDatabase {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param prefix Prefix option to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(prefix = '') {
/* Prefix if asked, or no prefix otherwise */
this.prefix = prefix || '';
}
/**
* Number of items in `localStorage`
*/
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(localStorage.length);
}
/**
* Gets an item value in `localStorage`
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
/* Get raw data */
const unparsedData = localStorage.getItem(this.prefixKey(key));
let parsedData;
/* No need to parse if data is `null` or `undefined` */
if ((unparsedData !== undefined) && (unparsedData !== null)) {
/* Try to parse */
/* Can fail if storage quota is exceeded */
try {
parsedData = JSON.parse(unparsedData);
localStorage.setItem(this.prefixKey(key), serializedData);
}

@@ -675,202 +714,175 @@ catch (error) {

}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(parsedData);
}
/**
* Store an item in `localStorage`
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
let serializedData = null;
/* Check if data can be serialized */
const dataPrototype = Object.getPrototypeOf(data);
if ((typeof data === 'object') && (data !== null) && !Array.isArray(data) &&
!((dataPrototype === Object.prototype) || (dataPrototype === null))) {
return throwError(new SerializationError());
/**
* Deletes an item in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
localStorage.removeItem(this.prefixKey(key));
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/* Try to stringify (can fail on circular references) */
try {
serializedData = JSON.stringify(data);
/**
* Deletes all items in `localStorage`
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
localStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
catch (error) {
return throwError(error);
/**
* Get all keys in `localStorage`
* Note the order of the keys may be inconsistent in Firefox
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return new Observable((subscriber) => {
/* Iteretate over all the indexes */
for (let index = 0; index < localStorage.length; index += 1) {
/* Cast as we are sure in this case the key is not `null` */
subscriber.next(this.getUnprefixedKey(index));
}
subscriber.complete();
}).pipe(
/* Required to work like other databases which are asynchronous */
observeOn(asyncScheduler));
}
/* Can fail if storage quota is exceeded */
try {
localStorage.setItem(this.prefixKey(key), serializedData);
}
catch (error) {
return throwError(error);
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes an item in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
localStorage.removeItem(this.prefixKey(key));
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes all items in `localStorage`
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
localStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Get all keys in `localStorage`
* Note the order of the keys may be inconsistent in Firefox
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return new Observable((subscriber) => {
/* Iteretate over all the indexes */
/**
* Check if a key exists in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Itérate over all indexes in storage */
for (let index = 0; index < localStorage.length; index += 1) {
/* Cast as we are sure in this case the key is not `null` */
subscriber.next(this.getUnprefixedKey(index));
if (key === this.getUnprefixedKey(index)) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(true);
}
}
subscriber.complete();
}).pipe(
/* Required to work like other databases which are asynchronous */
observeOn(asyncScheduler));
}
/**
* Check if a key exists in `localStorage`
* @param key The item's key
* @returns A RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Itérate over all indexes in storage */
for (let index = 0; index < localStorage.length; index += 1) {
if (key === this.getUnprefixedKey(index)) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(true);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(false);
}
/**
* Get an unprefixed key
* @param index Index of the key
* @returns The unprefixed key name if exists, `null` otherwise
*/
getUnprefixedKey(index) {
/* Get the key in storage: may have a prefix */
const prefixedKey = localStorage.key(index);
if (prefixedKey !== null) {
/* If no prefix, the key is already good, otherwrite strip the prefix */
return !this.prefix ? prefixedKey : prefixedKey.substr(this.prefix.length);
}
return null;
}
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(false);
}
/**
* Get an unprefixed key
* @param index Index of the key
* @returns The unprefixed key name if exists, `null` otherwise
*/
getUnprefixedKey(index) {
/* Get the key in storage: may have a prefix */
const prefixedKey = localStorage.key(index);
if (prefixedKey !== null) {
/* If no prefix, the key is already good, otherwrite strip the prefix */
return !this.prefix ? prefixedKey : prefixedKey.substr(this.prefix.length);
/**
* Add the prefix to a key
* @param key The key name
* @returns The prefixed key name
*/
prefixKey(key) {
return `${this.prefix}${key}`;
}
return null;
}
/**
* Add the prefix to a key
* @param key The key name
* @returns The prefixed key name
*/
prefixKey(key) {
return `${this.prefix}${key}`;
}
};
LocalStorageDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
LocalStorageDatabase.ɵprov = ɵɵdefineInjectable({ factory: function LocalStorageDatabase_Factory() { return new LocalStorageDatabase(ɵɵinject(LS_PREFIX)); }, token: LocalStorageDatabase, providedIn: "root" });
LocalStorageDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(LS_PREFIX))
], LocalStorageDatabase);
};
LocalStorageDatabase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
LocalStorageDatabase.ɵprov = ɵɵdefineInjectable({ factory: function LocalStorageDatabase_Factory() { return new LocalStorageDatabase(ɵɵinject(LS_PREFIX)); }, token: LocalStorageDatabase, providedIn: "root" });
LocalStorageDatabase = __decorate([
Injectable({
providedIn: 'root'
}),
__param(0, Inject(LS_PREFIX))
], LocalStorageDatabase);
return LocalStorageDatabase;
})();
let MemoryDatabase = class MemoryDatabase {
constructor() {
let MemoryDatabase = /** @class */ (() => {
let MemoryDatabase = class MemoryDatabase {
constructor() {
/**
* Memory storage
*/
this.memoryStorage = new Map();
}
/**
* Memory storage
* Number of items in memory
*/
this.memoryStorage = new Map();
}
/**
* Number of items in memory
*/
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.size);
}
/**
* Gets an item value in memory
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
const rawData = this.memoryStorage.get(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(rawData);
}
/**
* Sets an item in memory
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
this.memoryStorage.set(key, data);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes an item in memory
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
this.memoryStorage.delete(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes all items in memory
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
this.memoryStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Get all keys in memory
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return from(this.memoryStorage.keys());
}
/**
* Check if a key exists in memory
* @param key Key name
* @returns a RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.has(key));
}
};
MemoryDatabase.ɵprov = ɵɵdefineInjectable({ factory: function MemoryDatabase_Factory() { return new MemoryDatabase(); }, token: MemoryDatabase, providedIn: "root" });
MemoryDatabase = __decorate([
Injectable({
providedIn: 'root'
})
], MemoryDatabase);
get size() {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.size);
}
/**
* Gets an item value in memory
* @param key The item's key
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
*/
get(key) {
const rawData = this.memoryStorage.get(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(rawData);
}
/**
* Sets an item in memory
* @param key The item's key
* @param data The item's value
* @returns A RxJS `Observable` to wait the end of the operation
*/
set(key, data) {
this.memoryStorage.set(key, data);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes an item in memory
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*/
delete(key) {
this.memoryStorage.delete(key);
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Deletes all items in memory
* @returns A RxJS `Observable` to wait the end of the operation
*/
clear() {
this.memoryStorage.clear();
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(undefined);
}
/**
* Get all keys in memory
* @returns A RxJS `Observable` iterating on keys
*/
keys() {
/* Create an `Observable` from keys */
return from(this.memoryStorage.keys());
}
/**
* Check if a key exists in memory
* @param key Key name
* @returns a RxJS `Observable` telling if the key exists or not
*/
has(key) {
/* Wrap in a RxJS `Observable` to be consistent with other storages */
return of(this.memoryStorage.has(key));
}
};
MemoryDatabase.ɵprov = ɵɵdefineInjectable({ factory: function MemoryDatabase_Factory() { return new MemoryDatabase(); }, token: MemoryDatabase, providedIn: "root" });
MemoryDatabase = __decorate([
Injectable({
providedIn: 'root'
})
], MemoryDatabase);
return MemoryDatabase;
})();

@@ -928,19 +940,22 @@ /**

}
let LocalDatabase = class LocalDatabase {
};
LocalDatabase.ɵprov = ɵɵdefineInjectable({ factory: function LocalDatabase_Factory() { return localDatabaseFactory(ɵɵinject(PLATFORM_ID), ɵɵinject(LS_PREFIX), ɵɵinject(IDB_DB_NAME), ɵɵinject(IDB_STORE_NAME), ɵɵinject(IDB_DB_VERSION), ɵɵinject(IDB_NO_WRAP)); }, token: LocalDatabase, providedIn: "root" });
LocalDatabase = __decorate([
Injectable({
providedIn: 'root',
useFactory: localDatabaseFactory,
deps: [
PLATFORM_ID,
LS_PREFIX,
IDB_DB_NAME,
IDB_STORE_NAME,
IDB_DB_VERSION,
IDB_NO_WRAP,
]
})
], LocalDatabase);
let LocalDatabase = /** @class */ (() => {
let LocalDatabase = class LocalDatabase {
};
LocalDatabase.ɵprov = ɵɵdefineInjectable({ factory: function LocalDatabase_Factory() { return localDatabaseFactory(ɵɵinject(PLATFORM_ID), ɵɵinject(LS_PREFIX), ɵɵinject(IDB_DB_NAME), ɵɵinject(IDB_STORE_NAME), ɵɵinject(IDB_DB_VERSION), ɵɵinject(IDB_NO_WRAP)); }, token: LocalDatabase, providedIn: "root" });
LocalDatabase = __decorate([
Injectable({
providedIn: 'root',
useFactory: localDatabaseFactory,
deps: [
PLATFORM_ID,
LS_PREFIX,
IDB_DB_NAME,
IDB_STORE_NAME,
IDB_DB_VERSION,
IDB_NO_WRAP,
]
})
], LocalDatabase);
return LocalDatabase;
})();

@@ -962,397 +977,406 @@ /**

let StorageMap = class StorageMap {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param database Storage to use
* @param jsonValidator Validator service
* @param LSPrefix Prefix for `localStorage` keys to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(database, jsonValidator = new JSONValidator(), LSPrefix = '') {
this.database = database;
this.jsonValidator = jsonValidator;
this.LSPrefix = LSPrefix;
this.notifiers = new Map();
}
/**
* **Number of items** in storage, wrapped in an `Observable`.
*
* @example
* this.storageMap.size.subscribe((size) => {
* console.log(size);
* });
*/
get size() {
return this.database.size
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.size));
}
/**
* Tells you which storage engine is used. *Only useful for interoperability.*
* Note that due to some browsers issues in some special contexts
* (Firefox private mode and Safari cross-origin iframes),
* **this information may be wrong at initialization,**
* as the storage could fallback from `indexedDB` to `localStorage`
* only after a first read or write operation.
* @returns Storage engine used
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {}
*/
get backingEngine() {
if (this.database instanceof IndexedDBDatabase) {
return 'indexedDB';
let StorageMap = /** @class */ (() => {
let StorageMap = class StorageMap {
/**
* Constructor params are provided by Angular (but can also be passed manually in tests)
* @param database Storage to use
* @param jsonValidator Validator service
* @param LSPrefix Prefix for `localStorage` keys to avoid collision for multiple apps on the same subdomain or for interoperability
*/
constructor(database, jsonValidator = new JSONValidator(), LSPrefix = '') {
this.database = database;
this.jsonValidator = jsonValidator;
this.LSPrefix = LSPrefix;
this.notifiers = new Map();
}
else if (this.database instanceof LocalStorageDatabase) {
return 'localStorage';
/**
* **Number of items** in storage, wrapped in an `Observable`.
*
* @example
* this.storageMap.size.subscribe((size) => {
* console.log(size);
* });
*/
get size() {
return this.database.size
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.size));
}
else if (this.database instanceof MemoryDatabase) {
return 'memory';
/**
* Tells you which storage engine is used. *Only useful for interoperability.*
* Note that due to some browsers issues in some special contexts
* (Firefox private mode and Safari cross-origin iframes),
* **this information may be wrong at initialization,**
* as the storage could fallback from `indexedDB` to `localStorage`
* only after a first read or write operation.
* @returns Storage engine used
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {}
*/
get backingEngine() {
if (this.database instanceof IndexedDBDatabase) {
return 'indexedDB';
}
else if (this.database instanceof LocalStorageDatabase) {
return 'localStorage';
}
else if (this.database instanceof MemoryDatabase) {
return 'memory';
}
else {
return 'unknown';
}
}
else {
return 'unknown';
/**
* Info about `indexedDB` database. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version.
* **Values will be empty if the storage is not `indexedDB`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {
* const { database, store, version } = this.storageMap.backingStore;
* }
*/
get backingStore() {
return (this.database instanceof IndexedDBDatabase) ?
this.database.backingStore :
{ database: '', store: '', version: 0 };
}
}
/**
* Info about `indexedDB` database. *Only useful for interoperability.*
* @returns `indexedDB` database name, store name and database version.
* **Values will be empty if the storage is not `indexedDB`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'indexedDB') {
* const { database, store, version } = this.storageMap.backingStore;
* }
*/
get backingStore() {
return (this.database instanceof IndexedDBDatabase) ?
this.database.backingStore :
{ database: '', store: '', version: 0 };
}
/**
* Info about `localStorage` fallback storage. *Only useful for interoperability.*
* @returns `localStorage` prefix.
* **Values will be empty if the storage is not `localStorage`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'localStorage') {
* const { prefix } = this.storageMap.fallbackBackingStore;
* }
*/
get fallbackBackingStore() {
return (this.database instanceof LocalStorageDatabase) ?
{ prefix: this.database.prefix } :
{ prefix: '' };
}
get(key, schema) {
/* Get the data in storage */
return this.database.get(key).pipe(
/* Check if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.get(key)), mergeMap((data) => {
/* No need to validate if the data is empty */
if ((data === undefined) || (data === null)) {
return of(undefined);
}
else if (schema) {
/* Validate data against a JSON schema if provided */
if (!this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
/**
* Info about `localStorage` fallback storage. *Only useful for interoperability.*
* @returns `localStorage` prefix.
* **Values will be empty if the storage is not `localStorage`,**
* **so it should be used after an engine check**.
*
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/master/docs/INTEROPERABILITY.md}
*
* @example
* if (this.storageMap.backingEngine === 'localStorage') {
* const { prefix } = this.storageMap.fallbackBackingStore;
* }
*/
get fallbackBackingStore() {
return (this.database instanceof LocalStorageDatabase) ?
{ prefix: this.database.prefix } :
{ prefix: '' };
}
get(key, schema) {
/* Get the data in storage */
return this.database.get(key).pipe(
/* Check if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.get(key)), mergeMap((data) => {
/* No need to validate if the data is empty */
if ((data === undefined) || (data === null)) {
return of(undefined);
}
/* Data have been checked, so it's OK to cast */
else if (schema) {
/* Validate data against a JSON schema if provided */
if (!this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
}
/* Data have been checked, so it's OK to cast */
return of(data);
}
/* Cast to unknown as the data wasn't checked */
return of(data);
}
/* Cast to unknown as the data wasn't checked */
return of(data);
}));
}
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.set('key', 'value').subscribe(() => {});
*/
set(key, data, schema) {
/* Storing `undefined` or `null` is useless and can cause issues in `indexedDb` in some browsers,
* so removing item instead for all storages to have a consistent API */
if ((data === undefined) || (data === null)) {
return this.delete(key);
}));
}
/* Validate data against a JSON schema if provided */
if (schema && !this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
}
return this.database.set(key, data).pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.set(key, data)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, data); }));
}
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.delete('key').subscribe(() => {});
*/
delete(key) {
return this.database.delete(key).pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.delete(key)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, undefined); }));
}
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.clear().subscribe(() => {});
*/
clear() {
return this.database.clear().pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.clear()),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => {
for (const key of this.notifiers.keys()) {
this.notify(key, undefined);
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.set('key', 'value').subscribe(() => {});
*/
set(key, data, schema) {
/* Storing `undefined` or `null` is useless and can cause issues in `indexedDb` in some browsers,
* so removing item instead for all storages to have a consistent API */
if ((data === undefined) || (data === null)) {
return this.delete(key);
}
}));
}
/**
* Get all keys stored in storage. Note **this is an *iterating* `Observable`**:
* * if there is no key, the `next` callback will not be invoked,
* * if you need to wait the whole operation to end, be sure to act in the `complete` callback,
* as this `Observable` can emit several values and so will invoke the `next` callback several times.
* @returns A list of the keys wrapped in a RxJS `Observable`
*
* @example
* this.storageMap.keys().subscribe({
* next: (key) => { console.log(key); },
* complete: () => { console.log('Done'); },
* });
*/
keys() {
return this.database.keys()
/* Validate data against a JSON schema if provided */
if (schema && !this.jsonValidator.validate(data, schema)) {
return throwError(new ValidationError());
}
return this.database.set(key, data).pipe(
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.keys()));
}
/**
* Tells if a key exists in storage
* @returns A RxJS `Observable` telling if the key exists
*
* @example
* this.storageMap.has('key').subscribe((hasKey) => {
* if (hasKey) {}
* });
*/
has(key) {
return this.database.has(key)
this.catchIDBBroken(() => this.database.set(key, data)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, data); }));
}
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.delete('key').subscribe(() => {});
*/
delete(key) {
return this.database.delete(key).pipe(
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.has(key)));
}
watch(key, schema) {
/* Check if there is already a notifier and cast according to schema */
let notifier = this.notifiers.get(key);
if (!notifier) {
/* Create a notifier and cast according to schema */
notifier = new ReplaySubject(1);
/* Memorize the notifier */
this.notifiers.set(key, notifier);
/* Get the current item value */
this.get(key, schema).subscribe({
next: (result) => notifier.next(result),
error: (error) => notifier.error(error),
});
this.catchIDBBroken(() => this.database.delete(key)),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => { this.notify(key, undefined); }));
}
/* Only the public API of the `Observable` should be returned */
return notifier.asObservable();
}
/**
* Notify when a value changes
* @param key The item's key
* @param data The new value
*/
notify(key, value) {
const notifier = this.notifiers.get(key);
if (notifier) {
notifier.next(value);
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.storageMap.clear().subscribe(() => {});
*/
clear() {
return this.database.clear().pipe(
/* Catch if `indexedDb` is broken */
this.catchIDBBroken(() => this.database.clear()),
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
tap(() => {
for (const key of this.notifiers.keys()) {
this.notify(key, undefined);
}
}));
}
}
/**
* RxJS operator to catch if `indexedDB` is broken
* @param operationCallback Callback with the operation to redo
*/
catchIDBBroken(operationCallback) {
return catchError((error) => {
/* Check if `indexedDB` is broken based on error message (the specific error class seems to be lost in the process) */
if ((error !== undefined) && (error !== null) && (error.message === IDB_BROKEN_ERROR)) {
/* When storage is fully disabled in browser (via the "Block all cookies" option),
* just trying to check `localStorage` variable causes a security exception.
* Prevents https://github.com/cyrilletuzi/angular-async-local-storage/issues/118
*/
try {
if ('getItem' in localStorage) {
/* Fallback to `localStorage` if available */
this.database = new LocalStorageDatabase(this.LSPrefix);
/**
* Get all keys stored in storage. Note **this is an *iterating* `Observable`**:
* * if there is no key, the `next` callback will not be invoked,
* * if you need to wait the whole operation to end, be sure to act in the `complete` callback,
* as this `Observable` can emit several values and so will invoke the `next` callback several times.
* @returns A list of the keys wrapped in a RxJS `Observable`
*
* @example
* this.storageMap.keys().subscribe({
* next: (key) => { console.log(key); },
* complete: () => { console.log('Done'); },
* });
*/
keys() {
return this.database.keys()
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.keys()));
}
/**
* Tells if a key exists in storage
* @returns A RxJS `Observable` telling if the key exists
*
* @example
* this.storageMap.has('key').subscribe((hasKey) => {
* if (hasKey) {}
* });
*/
has(key) {
return this.database.has(key)
/* Catch if `indexedDb` is broken */
.pipe(this.catchIDBBroken(() => this.database.has(key)));
}
watch(key, schema) {
/* Check if there is already a notifier and cast according to schema */
let notifier = this.notifiers.get(key);
if (!notifier) {
/* Create a notifier and cast according to schema */
notifier = new ReplaySubject(1);
/* Memorize the notifier */
this.notifiers.set(key, notifier);
/* Get the current item value */
this.get(key, schema).subscribe({
next: (result) => notifier.next(result),
error: (error) => notifier.error(error),
});
}
/* Only the public API of the `Observable` should be returned */
return notifier.asObservable();
}
/**
* Notify when a value changes
* @param key The item's key
* @param data The new value
*/
notify(key, value) {
const notifier = this.notifiers.get(key);
if (notifier) {
notifier.next(value);
}
}
/**
* RxJS operator to catch if `indexedDB` is broken
* @param operationCallback Callback with the operation to redo
*/
catchIDBBroken(operationCallback) {
return catchError((error) => {
/* Check if `indexedDB` is broken based on error message (the specific error class seems to be lost in the process) */
if ((error !== undefined) && (error !== null) && (error.message === IDB_BROKEN_ERROR)) {
/* When storage is fully disabled in browser (via the "Block all cookies" option),
* just trying to check `localStorage` variable causes a security exception.
* Prevents https://github.com/cyrilletuzi/angular-async-local-storage/issues/118
*/
try {
if ('getItem' in localStorage) {
/* Fallback to `localStorage` if available */
this.database = new LocalStorageDatabase(this.LSPrefix);
}
else {
/* Fallback to memory storage otherwise */
this.database = new MemoryDatabase();
}
}
else {
catch (_a) {
/* Fallback to memory storage otherwise */
this.database = new MemoryDatabase();
}
/* Redo the operation */
return operationCallback();
}
catch (_a) {
/* Fallback to memory storage otherwise */
this.database = new MemoryDatabase();
else {
/* Otherwise, rethrow the error */
return throwError(error);
}
/* Redo the operation */
return operationCallback();
});
}
};
StorageMap.ctorParameters = () => [
{ type: LocalDatabase },
{ type: JSONValidator },
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
StorageMap.ɵprov = ɵɵdefineInjectable({ factory: function StorageMap_Factory() { return new StorageMap(ɵɵinject(LocalDatabase), ɵɵinject(JSONValidator), ɵɵinject(LS_PREFIX)); }, token: StorageMap, providedIn: "root" });
StorageMap = __decorate([
Injectable({
providedIn: 'root'
}),
__param(2, Inject(LS_PREFIX))
], StorageMap);
return StorageMap;
})();
let LocalStorage = /** @class */ (() => {
let LocalStorage = class LocalStorage {
/* Use the `StorageMap` service to avoid code duplication */
constructor(storageMap) {
this.storageMap = storageMap;
}
/**
* Number of items in storage wrapped in an `Observable`
*
* @example
* this.localStorage.length.subscribe((length) => {
* console.log(length);
* });
*/
get length() {
return this.storageMap.size;
}
getItem(key, schema) {
if (schema) {
/* Backward compatibility with version <= 7 */
const schemaFinal = ('schema' in schema) ? schema.schema : schema;
return this.storageMap.get(key, schemaFinal).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
}
else {
/* Otherwise, rethrow the error */
return throwError(error);
return this.storageMap.get(key).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
}
});
}
};
StorageMap.ctorParameters = () => [
{ type: LocalDatabase },
{ type: JSONValidator },
{ type: undefined, decorators: [{ type: Inject, args: [LS_PREFIX,] }] }
];
StorageMap.ɵprov = ɵɵdefineInjectable({ factory: function StorageMap_Factory() { return new StorageMap(ɵɵinject(LocalDatabase), ɵɵinject(JSONValidator), ɵɵinject(LS_PREFIX)); }, token: StorageMap, providedIn: "root" });
StorageMap = __decorate([
Injectable({
providedIn: 'root'
}),
__param(2, Inject(LS_PREFIX))
], StorageMap);
let LocalStorage = class LocalStorage {
/* Use the `StorageMap` service to avoid code duplication */
constructor(storageMap) {
this.storageMap = storageMap;
}
/**
* Number of items in storage wrapped in an `Observable`
*
* @example
* this.localStorage.length.subscribe((length) => {
* console.log(length);
* });
*/
get length() {
return this.storageMap.size;
}
getItem(key, schema) {
if (schema) {
/* Backward compatibility with version <= 7 */
const schemaFinal = ('schema' in schema) ? schema.schema : schema;
return this.storageMap.get(key, schemaFinal).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
}
else {
return this.storageMap.get(key).pipe(
/* Transform `undefined` into `null` to align with `localStorage` API */
map((value) => (value !== undefined) ? value : null));
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.set('key', 'value').subscribe(() => {});
*/
setItem(key, data, schema) {
return this.storageMap.set(key, data, schema).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
}
/**
* Set an item in storage.
* Note that setting `null` or `undefined` will remove the item to avoid some browsers issues.
* @param key The item's key
* @param data The item's value
* @param schema Optional JSON schema to validate the data
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.set('key', 'value').subscribe(() => {});
*/
setItem(key, data, schema) {
return this.storageMap.set(key, data, schema).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.delete('key').subscribe(() => {});
*/
removeItem(key) {
return this.storageMap.delete(key).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.clear().subscribe(() => {});
*/
clear() {
return this.storageMap.clear().pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
};
LocalStorage.ctorParameters = () => [
{ type: StorageMap }
];
LocalStorage.ɵprov = ɵɵdefineInjectable({ factory: function LocalStorage_Factory() { return new LocalStorage(ɵɵinject(StorageMap)); }, token: LocalStorage, providedIn: "root" });
LocalStorage = __decorate([
Injectable({
providedIn: 'root'
})
], LocalStorage);
/**
* Delete an item in storage
* @param key The item's key
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.delete('key').subscribe(() => {});
*/
removeItem(key) {
return this.storageMap.delete(key).pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
/**
* Delete all items in storage
* @returns A RxJS `Observable` to wait the end of the operation
*
* @example
* this.localStorage.clear().subscribe(() => {});
*/
clear() {
return this.storageMap.clear().pipe(
/* Transform `undefined` into `true` for backward compatibility with v7 */
mapTo(true));
}
};
LocalStorage.ctorParameters = () => [
{ type: StorageMap }
];
LocalStorage.ɵprov = ɵɵdefineInjectable({ factory: function LocalStorage_Factory() { return new LocalStorage(ɵɵinject(StorageMap)); }, token: LocalStorage, providedIn: "root" });
LocalStorage = __decorate([
Injectable({
providedIn: 'root'
})
], LocalStorage);
return LocalStorage;
})();
var StorageModule_1;
/**
* This module does not contain anything, it's only useful to provide options via `.forRoot()`.
*/
let StorageModule = StorageModule_1 = class StorageModule {
/**
* Only useful to provide options, otherwise it does nothing.
* **Must be used at initialization, ie. in `AppModule`, and must not be loaded again in another module.**
*
* @example
* NgModule({
* imports: [StorageModule.forRoot({
* LSPrefix: 'custom_',
* })]
* })
* export class AppModule
*/
static forRoot(config) {
return {
ngModule: StorageModule_1,
providers: [
config.LSPrefix ? { provide: LS_PREFIX, useValue: config.LSPrefix } : [],
config.IDBDBName ? { provide: IDB_DB_NAME, useValue: config.IDBDBName } : [],
config.IDBStoreName ? { provide: IDB_STORE_NAME, useValue: config.IDBStoreName } : [],
config.IDBDBVersion ? { provide: IDB_DB_VERSION, useValue: config.IDBDBVersion } : [],
(config.IDBNoWrap === false) ? { provide: IDB_NO_WRAP, useValue: config.IDBNoWrap } : [],
],
};
}
};
StorageModule = StorageModule_1 = __decorate([
NgModule()
], StorageModule);
let StorageModule = /** @class */ (() => {
var StorageModule_1;
let StorageModule = StorageModule_1 = class StorageModule {
/**
* Only useful to provide options, otherwise it does nothing.
* **Must be used at initialization, ie. in `AppModule`, and must not be loaded again in another module.**
*
* @example
* NgModule({
* imports: [StorageModule.forRoot({
* LSPrefix: 'custom_',
* })]
* })
* export class AppModule
*/
static forRoot(config) {
return {
ngModule: StorageModule_1,
providers: [
config.LSPrefix ? { provide: LS_PREFIX, useValue: config.LSPrefix } : [],
config.IDBDBName ? { provide: IDB_DB_NAME, useValue: config.IDBDBName } : [],
config.IDBStoreName ? { provide: IDB_STORE_NAME, useValue: config.IDBStoreName } : [],
config.IDBDBVersion ? { provide: IDB_DB_VERSION, useValue: config.IDBDBVersion } : [],
(config.IDBNoWrap === false) ? { provide: IDB_NO_WRAP, useValue: config.IDBNoWrap } : [],
],
};
}
};
StorageModule = StorageModule_1 = __decorate([
NgModule()
], StorageModule);
return StorageModule;
})();

@@ -1359,0 +1383,0 @@ /*

{
"name": "@ngx-pwa/local-storage",
"version": "10.0.0-1",
"version": "10.0.0-2",
"funding": {

@@ -29,7 +29,9 @@ "type": "github",

},
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"@angular/common": "^10.0.0 || ^10.0.0-next || ^10.0.0-rc",
"@angular/core": "^10.0.0 || ^10.0.0-next || ^10.0.0-rc",
"rxjs": "^6.5.3",
"tslib": "^1.10.0"
"@angular/common": "^10.0.0 || ^10.0.0-rc",
"@angular/core": "^10.0.0 || ^10.0.0-rc",
"rxjs": "^6.5.3"
},

@@ -36,0 +38,0 @@ "schematics": "./schematics/collection.json",

@@ -12,2 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.updateToV9 = exports.updateToV8 = void 0;
const schematics_1 = require("@angular-devkit/schematics");

@@ -14,0 +15,0 @@ const config_1 = require("../utility/config");

@@ -12,2 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getMainPath = exports.getAllMainPaths = exports.getAngularMajorVersion = exports.packageName = void 0;
const schematics_1 = require("@angular-devkit/schematics");

@@ -14,0 +15,0 @@ const dependencies_1 = require("@schematics/angular/utility/dependencies");

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateModuleToV9 = exports.updateModule = exports.addModule = void 0;
const schematics_1 = require("@angular-devkit/schematics");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const ng_ast_utils_1 = require("@schematics/angular/utility/ng-ast-utils");
const ts = require("typescript");
const ts = require("@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript");
const config_1 = require("./config");

@@ -8,0 +9,0 @@ /**

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc