UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

165 lines 22.9 kB
import { Injectable } from '@angular/core'; import { Platform } from '@ionic/angular'; import { toError } from '@iotize/app-common'; import { bufferToHexString, hexStringToBuffer, } from '@iotize/common/byte-converter'; import { NEVER, ReplaySubject, Subject } from 'rxjs'; import { catchError, filter, share, switchMap } from 'rxjs/operators'; import { debug } from '../../logger'; import { NFC } from '../../nfc'; import * as i0 from "@angular/core"; import * as i1 from "../../nfc"; import * as i2 from "@ionic/angular"; const TAG = 'NfcService'; export class NfcService { nfc; platform; _tagDiscoveredListener = new Subject(); tagDiscoveredEvents = this._tagDiscoveredListener.pipe(switchMap((v) => v), share()); _ndefDiscoveredListener = new ReplaySubject(); ndefDiscoveredEvents = this._ndefDiscoveredListener.pipe(switchMap((v) => v)); _tapDeviceDiscoveredEvent = new ReplaySubject(); tapDeviceDiscoveredEvent = this._tapDeviceDiscoveredEvent.pipe(switchMap((v) => v)); _setupTapDeviceDiscoveredListenerPromise; _setupTagDiscoveredListenerPromise; constructor(nfc, platform) { this.nfc = nfc; this.platform = platform; } async write(data) { try { await this.nfc.write(data); } catch (err) { if (err === 'cordova_not_available') { err = new Error(`NFC is not available on this device`); } throw err; } } async transceive(data) { const rawResponse = await this.nfc.transceive(data); const response = parseNFCTransceiveResponse(data, rawResponse); console.debug(`NFC transceive ${bufferToHexString(data)} => 0x${bufferToHexString(response)}`); return response; } async isEnabled() { try { return await this.nfc.enabled(); } catch (err) { console.error('NFC enabled error', err); return false; } } async setupTagDiscoveredListenerOnce() { if (this._setupTagDiscoveredListenerPromise) { return await this._setupTagDiscoveredListenerPromise; } else { return await this.setupTagDiscoveredListener(); } } async setupTapDeviceDiscoveredListener() { this._setupTapDeviceDiscoveredListenerPromise = createCatchSafePromise((resolve, reject) => { const tapDeviceDiscoveredListener = this.nfc.addTapDeviceListener(() => { resolve(); }, (err) => { reject(err); }); this._tapDeviceDiscoveredEvent.next(tapDeviceDiscoveredListener); }, 5000); await this._setupTapDeviceDiscoveredListenerPromise; } async setupTagDiscoveredListener() { this._setupTagDiscoveredListenerPromise = createCatchSafePromise((resolve, reject) => { debug(TAG, 'Adding TAG discovered listener...'); this._tagDiscoveredListener.next(this.nfc .addTagDiscoveredListener(() => { debug(TAG, 'NFC Tag discovered listener OK!'); resolve(); }, (error) => { debug(TAG, `NFC Tag discovered listener didn't start`, error); reject(error); }) .pipe(catchError((err) => { const error = toError(err); console.warn(`NFC Tag listener failed to initialize: ${error.message}`, err); reject(error); return NEVER; }), filter((event) => !!event) // First event is undefined ... )); }, 5000); await this._setupTagDiscoveredListenerPromise; } async setupNdefListener() { return await createCatchSafePromise((resolve, _reject) => { this._ndefDiscoveredListener.next(this.nfc .addNdefListener() // @warning callbacks are never called... .pipe(catchError((err) => { const error = toError(err); console.warn(`NDEF listener failed to initialize: ${error.message}`, err); return NEVER; }))); resolve(); }, 5000); } async closeNFC() { await this.nfc.close(); } /** * iOS specific commands */ async beginSessionFromTech(tech, alertMessage) { if (!this.platform.is('ios')) { return; } return this.nfc.beginSessionFromTech(tech, alertMessage); } async closeSession() { return this.nfc.closeSession(); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NfcService, deps: [{ token: i1.NFC }, { token: i2.Platform }], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NfcService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NfcService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: () => [{ type: i1.NFC }, { type: i2.Platform }] }); function createCatchSafePromise(callback, timeout) { return new Promise((resolve, reject) => { if (timeout) { setTimeout(() => { reject(new Error(`Native code did not respond before timeout of ${timeout}ms`)); }, timeout); } try { callback(resolve, reject); } catch (error) { reject(error); } }); } function parseNFCTransceiveResponse(frame, resultBufferOrString) { if (!resultBufferOrString) { return new Uint8Array(0); } if (typeof resultBufferOrString === 'object') { if ('error' in resultBufferOrString) { const errorString = resultBufferOrString.error === 'cordova_not_available' ? `NFC is not available` : resultBufferOrString.error; throw new Error(`Failed to NFC transceive frame 0x${bufferToHexString(frame)} (error: ${errorString})`); } } if (typeof resultBufferOrString === 'string') { return hexStringToBuffer(resultBufferOrString); } else { return Buffer.from(resultBufferOrString); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZjLXNlcnZpY2Uuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9zcmMvbGliL3RhcC1zY2FubmVyL3RhcC1zY2FubmVyLW5mYy9uZmMtc2VydmljZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGlCQUFpQixHQUNsQixNQUFNLCtCQUErQixDQUFDO0FBRXZDLE9BQU8sRUFBRSxLQUFLLEVBQWMsYUFBYSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyQyxPQUFPLEVBQUUsR0FBRyxFQUFzQixNQUFNLFdBQVcsQ0FBQzs7OztBQUdwRCxNQUFNLEdBQUcsR0FBRyxZQUFZLENBQUM7QUFlekIsTUFBTSxPQUFPLFVBQVU7SUE4QkY7SUFBa0I7SUE3QjdCLHNCQUFzQixHQUFHLElBQUksT0FBTyxFQUV6QyxDQUFDO0lBRUssbUJBQW1CLEdBQzFCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQzlCLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQ25CLEtBQUssRUFBRSxDQUNSLENBQUM7SUFFYSx1QkFBdUIsR0FBRyxJQUFJLGFBQWEsRUFFekQsQ0FBQztJQUVLLG9CQUFvQixHQUFHLElBQUksQ0FBQyx1QkFB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QUNQLGlEQUFpRCxPQUFPLElBQUksQ0FDN0QsQ0FDRixDQUFDO1lBQ0osQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2QsQ0FBQztRQUNELElBQUksQ0FBQztZQUNILFFBQVEsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDNUIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsMEJBQTBCLENBQ2pDLEtBQWlCLEVBQ2pCLG9CQUtRO0lBRVIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDMUIsT0FBTyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQ0QsSUFBSSxPQUFPLG9CQUFvQixLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzdDLElBQUksT0FBTyxJQUFJLG9CQUFvQixFQUFFLENBQUM7WUFDcEMsTUFBTSxXQUFXLEdBQ2Ysb0JBQW9CLENBQUMsS0FBSyxLQUFLLHVCQUF1QjtnQkFDcEQsQ0FBQyxDQUFDLHNCQUFzQjtnQkFDeEIsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQztZQUNqQyxNQUFNLElBQUksS0FBSyxDQUNiLG9DQUFvQyxpQkFBaUIsQ0FDbkQsS0FBSyxDQUNOLFlBQVksV0FBVyxHQUFHLENBQzVCLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksT0FBTyxvQkFBb0IsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM3QyxPQUFPLGlCQUFpQixDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDakQsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0JBQW1DLENBQUMsQ0FBQztJQUMxRCxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgdG9FcnJvciB9IGZyb20gJ0Bpb3RpemUvYXBwLWNvbW1vbic7XG5pbXBvcnQge1xuICBidWZmZXJUb0hleFN0cmluZyxcbiAgaGV4U3RyaW5nVG9CdWZmZXIsXG59IGZyb20gJ0Bpb3RpemUvY29tbW9uL2J5dGUtY29udmVydGVyJztcbmltcG9ydCB7IEVuY3J5cHRpb25PcHRpb25zIH0gZnJvbSAnQGlvdGl6ZS90YXAvYXV0aCc7XG5pbXBvcnQgeyBORVZFUiwgT2JzZXJ2YWJsZSwgUmVwbGF5U3ViamVjdCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZmlsdGVyLCBzaGFyZSwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBkZWJ1ZyB9IGZyb20gJy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBORkMsIE5kZWZFdmVudCwgTmRlZlRhZyB9IGZyb20gJy4uLy4uL25mYyc7XG5pbXBvcnQgeyBUYWdEaXNjb3ZlcmVkRXZlbnQgfSBmcm9tICcuL2RlZmluaXRpb25zJztcblxuY29uc3QgVEFHID0gJ05mY1NlcnZpY2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlY292ZXJhYmxlVGFwU3RhdGVFdmVudCB7XG4gIHRhZzogTmRlZlRhZztcbiAgdGFwOiBSZWNvdmVyYWJsZVRhcFN0YXRlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY292ZXJhYmxlVGFwU3RhdGUge1xuICBuZmNQYWlyaW5nRG9uZT86IGJvb2xlYW47XG4gIGVuY3J5cHRpb24/OiBFbmNyeXB0aW9uT3B0aW9ucztcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIE5mY1NlcnZpY2Uge1xuICBwcml2YXRlIF90YWdEaXNjb3ZlcmVkTGlzdGVuZXIgPSBuZXcgU3ViamVjdDxcbiAgICBPYnNlcnZhYmxlPFRhZ0Rpc2NvdmVyZWRFdmVudD5cbiAgPigpO1xuXG4gIHJlYWRvbmx5IHRhZ0Rpc2NvdmVyZWRFdmVudHM6IE9ic2VydmFibGU8VGFnRGlzY292ZXJlZEV2ZW50PiA9XG4gICAgdGhpcy5fdGFnRGlzY292ZXJlZExpc3RlbmVyLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKHYpID0+IHYpLFxuICAgICAgc2hhcmUoKVxuICAgICk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbmRlZkRpc2NvdmVyZWRMaXN0ZW5lciA9IG5ldyBSZXBsYXlTdWJqZWN0PFxuICAgIE9ic2VydmFibGU8TmRlZkV2ZW50PlxuICA+KCk7XG5cbiAgcmVhZG9ubHkgbmRlZkRpc2NvdmVyZWRFdmVudHMgPSB0aGlzLl9uZGVmRGlzY292ZXJlZExpc3RlbmVyLnBpcGUoXG4gICAgc3dpdGNoTWFwKCh2KSA9PiB2KVxuICApO1xuXG4gIHByaXZhdGUgX3RhcERldmljZURpc2NvdmVyZWRFdmVudCA9IG5ldyBSZXBsYXlTdWJqZWN0PFxuICAgIE9ic2VydmFibGU8UmVjb3ZlcmFibGVUYXBTdGF0ZUV2ZW50PlxuICA+KCk7XG5cbiAgcmVhZG9ubHkgdGFwRGV2aWNlRGlzY292ZXJlZEV2ZW50ID0gdGhpcy5fdGFwRGV2aWNlRGlzY292ZXJlZEV2ZW50LnBpcGUoXG4gICAgc3dpdGNoTWFwKCh2KSA9PiB2KVxuICApO1xuXG4gIHByaXZhdGUgX3NldHVwVGFwRGV2aWNlRGlzY292ZXJlZExpc3RlbmVyUHJvbWlzZT86IFByb21pc2U8dm9pZD47XG4gIHByaXZhdGUgX3NldHVwVGFnRGlzY292ZXJlZExpc3RlbmVyUHJvbWlzZT86IFByb21pc2U8dm9pZD47XG5cbiAgY29uc3RydWN0b3IocHVibGljIG5mYzogTkZDLCBwcml2YXRlIHBsYXRmb3JtOiBQbGF0Zm9ybSkge31cblxuICBhc3luYyB3cml0ZShkYXRhOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLm5mYy53cml0ZShkYXRhKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChlcnIgPT09ICdjb3Jkb3ZhX25vdF9hdmFpbGFibGUnKSB7XG4gICAgICAgIGVyciA9IG5ldyBFcnJvcihgTkZDIGlzIG5vdCBhdmFpbGFibGUgb24gdGhpcyBkZXZpY2VgKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cblxuICBhc3luYyB0cmFuc2NlaXZlKGRhdGE6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgICBjb25zdCByYXdSZXNwb25zZSA9IGF3YWl0IHRoaXMubmZjLnRyYW5zY2VpdmUoZGF0YSk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBwYXJzZU5GQ1RyYW5zY2VpdmVSZXNwb25zZShkYXRhLCByYXdSZXNwb25zZSk7XG4gICAgY29uc29sZS5kZWJ1ZyhcbiAgICAgIGBORkMgdHJhbnNjZWl2ZSAke2J1ZmZlclRvSGV4U3RyaW5nKGRhdGEpfSA9PiAweCR7YnVmZmVyVG9IZXhTdHJpbmcoXG4gICAgICAgIHJlc3BvbnNlXG4gICAgICApfWBcbiAgICApO1xuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuXG4gIGFzeW5jIGlzRW5hYmxlZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMubmZjLmVuYWJsZWQoKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ05GQyBlbmFibGVkIGVycm9yJywgZXJyKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzZXR1cFRhZ0Rpc2NvdmVyZWRMaXN0ZW5lck9uY2UoKSB7XG4gICAgaWYgKHRoaXMuX3NldHVwVGFnRGlzY292ZXJlZExpc3RlbmVyUHJvbWlzZSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3NldHVwVGFnRGlzY292ZXJlZExpc3RlbmVyUHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2V0dXBUYWdEaXNjb3ZlcmVkTGlzdGVuZXIoKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzZXR1cFRhcERldmljZURpc2NvdmVyZWRMaXN0ZW5lcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLl9zZXR1cFRhcERldmljZURpc2NvdmVyZWRMaXN0ZW5lclByb21pc2UgPVxuICAgICAgY3JlYXRlQ2F0Y2hTYWZlUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHRhcERldmljZURpc2NvdmVyZWRMaXN0ZW5lciA9IHRoaXMubmZjLmFkZFRhcERldmljZUxpc3RlbmVyKFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIChlcnI/OiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICB0aGlzLl90YXBEZXZpY2VEaXNjb3ZlcmVkRXZlbnQubmV4dCh0YXBEZXZpY2VEaXNjb3ZlcmVkTGlzdGVuZXIpO1xuICAgICAgfSwgNTAwMCk7XG4gICAgYXdhaXQgdGhpcy5fc2V0dXBUYXBEZXZpY2VEaXNjb3ZlcmVkTGlzdGVuZXJQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgc2V0dXBUYWdEaXNjb3ZlcmVkTGlzdGVuZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5fc2V0dXBUYWdEaXNjb3ZlcmVkTGlzdGVuZXJQcm9taXNlID0gY3JlYXRlQ2F0Y2hTYWZlUHJvbWlzZTx2b2lkPihcbiAgICAgIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgZGVidWcoVEFHLCAnQWRkaW5nIFRBRyBkaXNjb3ZlcmVkIGxpc3RlbmVyLi4uJyk7XG4gICAgICAgIHRoaXMuX3RhZ0Rpc2NvdmVyZWRMaXN0ZW5lci5uZXh0KFxuICAgICAgICAgIHRoaXMubmZjXG4gICAgICAgICAgICAuYWRkVGFnRGlzY292ZXJlZExpc3RlbmVyKFxuICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZGVidWcoVEFHLCAnTkZDIFRhZyBkaXNjb3ZlcmVkIGxpc3RlbmVyIE9LIScpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGRlYnVnKFRBRywgYE5GQyBUYWcgZGlzY292ZXJlZCBsaXN0ZW5lciBkaWRuJ3Qgc3RhcnRgLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIGNhdGNoRXJyb3IoKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gdG9FcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgIGBORkMgVGFnIGxpc3RlbmVyIGZhaWxlZCB0byBpbml0aWFsaXplOiAke2Vycm9yLm1lc3NhZ2V9YCxcbiAgICAgICAgICAgICAgICAgIGVyclxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gTkVWRVI7XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBmaWx0ZXIoKGV2ZW50KSA9PiAhIWV2ZW50KSAvLyBGaXJzdCBldmVudCBpcyB1bmRlZmluZWQgLi4uXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9LFxuICAgICAgNTAwMFxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5fc2V0dXBUYWdEaXNjb3ZlcmVkTGlzdGVuZXJQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgc2V0dXBOZGVmTGlzdGVuZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGF3YWl0IGNyZWF0ZUNhdGNoU2FmZVByb21pc2U8dm9pZD4oKHJlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgIHRoaXMuX25kZWZEaXNjb3ZlcmVkTGlzdGVuZXIubmV4dChcbiAgICAgICAgdGhpcy5uZmNcbiAgICAgICAgICAuYWRkTmRlZkxpc3RlbmVyKCkgLy8gQHdhcm5pbmcgY2FsbGJhY2tzIGFyZSBuZXZlciBjYWxsZWQuLi5cbiAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgIGNhdGNoRXJyb3IoKGVycikgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IHRvRXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgIGBOREVGIGxpc3RlbmVyIGZhaWxlZCB0byBpbml0aWFsaXplOiAke2Vycm9yLm1lc3NhZ2V9YCxcbiAgICAgICAgICAgICAgICBlcnJcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIE5FVkVSO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICApO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0sIDUwMDApO1xuICB9XG5cbiAgYXN5bmMgY2xvc2VORkMoKSB7XG4gICAgYXdhaXQgdGhpcy5uZmMuY2xvc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpT1Mgc3BlY2lmaWMgY29tbWFuZHNcbiAgICovXG4gIGFzeW5jIGJlZ2luU2Vzc2lvbkZyb21UZWNoKFxuICAgIHRlY2g6IHN0cmluZyxcbiAgICBhbGVydE1lc3NhZ2U/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLnBsYXRmb3JtLmlzKCdpb3MnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5uZmMuYmVnaW5TZXNzaW9uRnJvbVRlY2godGVjaCwgYWxlcnRNZXNzYWdlKTtcbiAgfVxuXG4gIGFzeW5jIGNsb3NlU2Vzc2lvbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5uZmMuY2xvc2VTZXNzaW9uKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2F0Y2hTYWZlUHJvbWlzZTxUPihcbiAgY2FsbGJhY2s6IChcbiAgICByZXNvbHZlOiAodmFsdWU6IFQgfCBQcm9taXNlTGlrZTxUPikgPT4gdm9pZCxcbiAgICByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWRcbiAgKSA9PiB2b2lkLFxuICB0aW1lb3V0PzogbnVtYmVyXG4pOiBQcm9taXNlPFQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHJlamVjdChcbiAgICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgTmF0aXZlIGNvZGUgZGlkIG5vdCByZXNwb25kIGJlZm9yZSB0aW1lb3V0IG9mICR7dGltZW91dH1tc2BcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9LCB0aW1lb3V0KTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNhbGxiYWNrKHJlc29sdmUsIHJlamVjdCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VORkNUcmFuc2NlaXZlUmVzcG9uc2UoXG4gIGZyYW1lOiBVaW50OEFycmF5LFxuICByZXN1bHRCdWZmZXJPclN0cmluZzpcbiAgICB8IEFycmF5QnVmZmVyXG4gICAgfCBzdHJpbmdcbiAgICB8IHsgZXJyb3I/OiBzdHJpbmcgfVxuICAgIHwgdW5kZWZpbmVkXG4gICAgfCBudWxsXG4pIHtcbiAgaWYgKCFyZXN1bHRCdWZmZXJPclN0cmluZykge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheSgwKTtcbiAgfVxuICBpZiAodHlwZW9mIHJlc3VsdEJ1ZmZlck9yU3RyaW5nID09PSAnb2JqZWN0Jykge1xuICAgIGlmICgnZXJyb3InIGluIHJlc3VsdEJ1ZmZlck9yU3RyaW5nKSB7XG4gICAgICBjb25zdCBlcnJvclN0cmluZyA9XG4gICAgICAgIHJlc3VsdEJ1ZmZlck9yU3RyaW5nLmVycm9yID09PSAnY29yZG92YV9ub3RfYXZhaWxhYmxlJ1xuICAgICAgICAgID8gYE5GQyBpcyBub3QgYXZhaWxhYmxlYFxuICAgICAgICAgIDogcmVzdWx0QnVmZmVyT3JTdHJpbmcuZXJyb3I7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gTkZDIHRyYW5zY2VpdmUgZnJhbWUgMHgke2J1ZmZlclRvSGV4U3RyaW5nKFxuICAgICAgICAgIGZyYW1lXG4gICAgICAgICl9IChlcnJvcjogJHtlcnJvclN0cmluZ30pYFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHJlc3VsdEJ1ZmZlck9yU3RyaW5nID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBoZXhTdHJpbmdUb0J1ZmZlcihyZXN1bHRCdWZmZXJPclN0cmluZyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHJlc3VsdEJ1ZmZlck9yU3RyaW5nIGFzIEFycmF5QnVmZmVyKTtcbiAgfVxufVxuIl19