angular-weblineindia-qrcode-scanner
Version:
An AngularJS based Barcode / QRCode scanner component.
274 lines • 27.1 kB
JavaScript
/// <reference path="./image-capture.d.ts" />
import * as tslib_1 from "tslib";
import { BrowserMultiFormatReader, ChecksumException, FormatException, NotFoundException } from '@zxing/library';
import { BehaviorSubject } from 'rxjs';
/**
* Based on zxing-typescript BrowserCodeReader
*/
var BrowserMultiFormatContinuousReader = /** @class */ (function (_super) {
tslib_1.__extends(BrowserMultiFormatContinuousReader, _super);
function BrowserMultiFormatContinuousReader() {
var _this = _super !== null && _super.apply(this, arguments) || this;
/**
* Says if there's a torch available for the current device.
*/
_this._isTorchAvailable = new BehaviorSubject(undefined);
return _this;
}
Object.defineProperty(BrowserMultiFormatContinuousReader.prototype, "isTorchAvailable", {
/**
* Exposes _tochAvailable .
*/
get: function () {
return this._isTorchAvailable.asObservable();
},
enumerable: true,
configurable: true
});
/**
* Starts the decoding from the current or a new video element.
*
* @param callbackFn The callback to be executed after every scan attempt
* @param deviceId The device's to be used Id
* @param videoSource A new video element
*/
BrowserMultiFormatContinuousReader.prototype.continuousDecodeFromInputVideoDevice = function (deviceId, videoSource) {
var _this = this;
this.reset();
// Keeps the deviceId between scanner resets.
if (typeof deviceId !== 'undefined') {
this.deviceId = deviceId;
}
if (typeof navigator === 'undefined') {
return;
}
var scan$ = new BehaviorSubject({});
try {
// this.decodeFromInputVideoDeviceContinuously(deviceId, videoSource, (result, error) => scan$.next({ result, error }));
this.getStreamForDevice({ deviceId: deviceId })
.then(function (stream) { return _this.attachStreamToVideoAndCheckTorch(stream, videoSource); })
.then(function (videoElement) { return _this.decodeOnSubject(scan$, videoElement, _this.timeBetweenScansMillis); });
}
catch (e) {
scan$.error(e);
}
this._setScanStream(scan$);
// @todo Find a way to emit a complete event on the scan stream once it's finished.
return scan$.asObservable();
};
/**
* Gets the media stream for certain device.
* Falls back to any available device if no `deviceId` is defined.
*/
BrowserMultiFormatContinuousReader.prototype.getStreamForDevice = function (_a) {
var deviceId = _a.deviceId;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var constraints, stream;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
constraints = this.getUserMediaConstraints(deviceId);
return [4 /*yield*/, navigator.mediaDevices.getUserMedia(constraints)];
case 1:
stream = _b.sent();
return [2 /*return*/, stream];
}
});
});
};
/**
* Creates media steram constraints for certain `deviceId`.
* Falls back to any environment available device if no `deviceId` is defined.
*/
BrowserMultiFormatContinuousReader.prototype.getUserMediaConstraints = function (deviceId) {
var video = typeof deviceId === 'undefined'
? { facingMode: { exact: 'environment' } }
: { deviceId: { exact: deviceId } };
var constraints = { video: video };
return constraints;
};
/**
* Enables and disables the device torch.
*/
BrowserMultiFormatContinuousReader.prototype.setTorch = function (on) {
if (!this._isTorchAvailable.value) {
// compatibility not checked yet
return;
}
var tracks = this.getVideoTracks(this.stream);
if (on) {
this.applyTorchOnTracks(tracks, true);
}
else {
this.applyTorchOnTracks(tracks, false);
// @todo check possibility to disable torch without restart
this.restart();
}
};
/**
* Update the torch compatibility state and attachs the stream to the preview element.
*/
BrowserMultiFormatContinuousReader.prototype.attachStreamToVideoAndCheckTorch = function (stream, videoSource) {
this.updateTorchCompatibility(stream);
return this.attachStreamToVideo(stream, videoSource);
};
/**
* Checks if the stream supports torch control.
*
* @param stream The media stream used to check.
*/
BrowserMultiFormatContinuousReader.prototype.updateTorchCompatibility = function (stream) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var e_1, _a, tracks, tracks_1, tracks_1_1, track, e_1_1;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
tracks = this.getVideoTracks(stream);
_b.label = 1;
case 1:
_b.trys.push([1, 6, 7, 8]);
tracks_1 = tslib_1.__values(tracks), tracks_1_1 = tracks_1.next();
_b.label = 2;
case 2:
if (!!tracks_1_1.done) return [3 /*break*/, 5];
track = tracks_1_1.value;
return [4 /*yield*/, this.isTorchCompatible(track)];
case 3:
if (_b.sent()) {
this._isTorchAvailable.next(true);
return [3 /*break*/, 5];
}
_b.label = 4;
case 4:
tracks_1_1 = tracks_1.next();
return [3 /*break*/, 2];
case 5: return [3 /*break*/, 8];
case 6:
e_1_1 = _b.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 8];
case 7:
try {
if (tracks_1_1 && !tracks_1_1.done && (_a = tracks_1.return)) _a.call(tracks_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
case 8: return [2 /*return*/];
}
});
});
};
/**
*
* @param stream The video stream where the tracks gonna be extracted from.
*/
BrowserMultiFormatContinuousReader.prototype.getVideoTracks = function (stream) {
var tracks = [];
try {
tracks = stream.getVideoTracks();
}
finally {
return tracks || [];
}
};
/**
*
* @param track The media stream track that will be checked for compatibility.
*/
BrowserMultiFormatContinuousReader.prototype.isTorchCompatible = function (track) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var compatible, imageCapture, capabilities;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
compatible = false;
_a.label = 1;
case 1:
_a.trys.push([1, , 3, 4]);
imageCapture = new ImageCapture(track);
return [4 /*yield*/, imageCapture.getPhotoCapabilities()];
case 2:
capabilities = _a.sent();
compatible = !!capabilities['torch'] || ('fillLightMode' in capabilities && capabilities.fillLightMode.length !== 0);
return [3 /*break*/, 4];
case 3: return [2 /*return*/, compatible];
case 4: return [2 /*return*/];
}
});
});
};
/**
* Apply the torch setting in all received tracks.
*/
BrowserMultiFormatContinuousReader.prototype.applyTorchOnTracks = function (tracks, state) {
tracks.forEach(function (track) { return track.applyConstraints({
advanced: [{ torch: state, fillLightMode: state ? 'torch' : 'none' }]
}); });
};
/**
* Correctly sets a new scanStream value.
*/
BrowserMultiFormatContinuousReader.prototype._setScanStream = function (scan$) {
// cleans old stream
this._cleanScanStream();
// sets new stream
this.scanStream = scan$;
};
/**
* Cleans any old scan stream value.
*/
BrowserMultiFormatContinuousReader.prototype._cleanScanStream = function () {
if (this.scanStream && !this.scanStream.isStopped) {
this.scanStream.complete();
}
this.scanStream = null;
};
/**
* Decodes values in a stream with delays between scans.
*
* @param scan$ The subject to receive the values.
* @param videoElement The video element the decode will be applied.
* @param delay The delay between decode results.
*/
BrowserMultiFormatContinuousReader.prototype.decodeOnSubject = function (scan$, videoElement, delay) {
var _this = this;
// stops loop
if (scan$.isStopped) {
return;
}
var result;
try {
result = this.decode(videoElement);
scan$.next({ result: result });
}
catch (error) {
// stream cannot stop on fails.
if (!error ||
// scan Failure - found nothing, no error
error instanceof NotFoundException ||
// scan Error - found the QR but got error on decoding
error instanceof ChecksumException ||
error instanceof FormatException) {
scan$.next({ error: error });
}
else {
scan$.error(error);
}
}
finally {
var timeout = !result ? 0 : delay;
setTimeout(function () { return _this.decodeOnSubject(scan$, videoElement, delay); }, timeout);
}
};
/**
* Restarts the scanner.
*/
BrowserMultiFormatContinuousReader.prototype.restart = function () {
// reset
// start
return this.continuousDecodeFromInputVideoDevice(this.deviceId, this.videoElement);
};
return BrowserMultiFormatContinuousReader;
}(BrowserMultiFormatReader));
export { BrowserMultiFormatContinuousReader };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci1tdWx0aS1mb3JtYXQtY29udGludW91cy1yZWFkZXIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Aenhpbmcvbmd4LXNjYW5uZXIvIiwic291cmNlcyI6WyJsaWIvYnJvd3Nlci1tdWx0aS1mb3JtYXQtY29udGludW91cy1yZWFkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkNBQTZDOztBQUU3QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFVLE1BQU0sZ0JBQWdCLENBQUM7QUFDekgsT0FBTyxFQUFFLGVBQWUsRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUduRDs7R0FFRztBQUNIO0lBQXdELDhEQUF3QjtJQUFoRjtRQUFBLHFFQXVQQztRQTlPQzs7V0FFRztRQUNLLHVCQUFpQixHQUFHLElBQUksZUFBZSxDQUFVLFNBQVMsQ0FBQyxDQUFDOztJQTJPdEUsQ0FBQztJQWxQQyxzQkFBVyxnRUFBZ0I7UUFIM0I7O1dBRUc7YUFDSDtZQUNFLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQy9DLENBQUM7OztPQUFBO0lBaUJEOzs7Ozs7T0FNRztJQUNJLGlGQUFvQyxHQUEzQyxVQUNFLFFBQWlCLEVBQ2pCLFdBQThCO1FBRmhDLGlCQWdDQztRQTNCQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFYiw2Q0FBNkM7UUFDN0MsSUFBSSxPQUFPLFFBQVEsS0FBSyxXQUFXLEVBQUU7WUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7U0FDMUI7UUFFRCxJQUFJLE9BQU8sU0FBUyxLQUFLLFdBQVcsRUFBRTtZQUNwQyxPQUFPO1NBQ1I7UUFFRCxJQUFNLEtBQUssR0FBRyxJQUFJLGVBQWUsQ0FBaUIsRUFBRSxDQUFDLENBQUM7UUFFdEQsSUFBSTtZQUNGLHdIQUF3SDtZQUN4SCxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxRQUFRLFVBQUEs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S0FBSyxDQUFDLEVBQWhELENBQWdELEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDN0U7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxvREFBTyxHQUFmO1FBQ0UsUUFBUTtRQUNSLFFBQVE7UUFDUixPQUFPLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBRUgseUNBQUM7QUFBRCxDQUFDLEFBdlBELENBQXdELHdCQUF3QixHQXVQL0UiLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi9pbWFnZS1jYXB0dXJlLmQudHNcIiAvPlxuXG5pbXBvcnQgeyBCcm93c2VyTXVsdGlGb3JtYXRSZWFkZXIsIENoZWNrc3VtRXhjZXB0aW9uLCBGb3JtYXRFeGNlcHRpb24sIE5vdEZvdW5kRXhjZXB0aW9uLCBSZXN1bHQgfSBmcm9tICdAenhpbmcvbGlicmFyeSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFJlc3VsdEFuZEVycm9yIH0gZnJvbSAnLi9SZXN1bHRBbmRFcnJvcic7XG5cbi8qKlxuICogQmFzZWQgb24genhpbmctdHlwZXNjcmlwdCBCcm93c2VyQ29kZVJlYWRlclxuICovXG5leHBvcnQgY2xhc3MgQnJvd3Nlck11bHRpRm9ybWF0Q29udGludW91c1JlYWRlciBleHRlbmRzIEJyb3dzZXJNdWx0aUZvcm1hdFJlYWRlciB7XG5cbiAgLyoqXG4gICAqIEV4cG9zZXMgX3RvY2hBdmFpbGFibGUgLlxuICAgKi9cbiAgcHVibGljIGdldCBpc1RvcmNoQXZhaWxhYmxlKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLl9pc1RvcmNoQXZhaWxhYmxlLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNheXMgaWYgdGhlcmUncyBhIHRvcmNoIGF2YWlsYWJsZSBmb3IgdGhlIGN1cnJlbnQgZGV2aWNlLlxuICAgKi9cbiAgcHJpdmF0ZSBfaXNUb3JjaEF2YWlsYWJsZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4odW5kZWZpbmVkKTtcblxuICAvKipcbiAgICogVGhlIGRldmljZSBpZCBvZiB0aGUgY3VycmVudCBtZWRpYSBkZXZpY2UuXG4gICAqL1xuICBwcml2YXRlIGRldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElmIHRoZXJlJ3Mgc29tZSBzY2FuIHN0cmVhbSBvcGVuLCBpdCBzaGFsIGJlIGhlcmUuXG4gICAqL1xuICBwcml2YXRlIHNjYW5TdHJlYW06IEJlaGF2aW9yU3ViamVjdDxSZXN1bHRBbmRFcnJvcj47XG5cbiAgLyoqXG4gICAqIFN0YXJ0cyB0aGUgZGVjb2RpbmcgZnJvbSB0aGUgY3VycmVudCBvciBhIG5ldyB2aWRlbyBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2tGbiBUaGUgY2FsbGJhY2sgdG8gYmUgZXhlY3V0ZWQgYWZ0ZXIgZXZlcnkgc2NhbiBhdHRlbXB0XG4gICAqIEBwYXJhbSBkZXZpY2VJZCBUaGUgZGV2aWNlJ3MgdG8gYmUgdXNlZCBJZFxuICAgKiBAcGFyYW0gdmlkZW9Tb3VyY2UgQSBuZXcgdmlkZW8gZWxlbWVudFxuICAgKi9cbiAgcHVibGljIGNvbnRpbnVvdXNEZWNvZGVGcm9tSW5wdXRWaWRlb0RldmljZShcbiAgICBkZXZpY2VJZD86IHN0cmluZyxcbiAgICB2aWRlb1NvdXJjZT86IEhUTUxWaWRlb0VsZW1lbnRcbiAgKTogT2JzZXJ2YWJsZTxSZXN1bHRBbmRFcnJvcj4ge1xuXG4gICAgdGhpcy5yZXNldCgpO1xuXG4gICAgLy8gS2VlcHMgdGhlIGRldmljZUlkIGJldHdlZW4gc2Nhbm5lciByZXNldHMuXG4gICAgaWYgKHR5cGVvZiBkZXZpY2VJZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuZGV2aWNlSWQgPSBkZXZpY2VJZDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzY2FuJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UmVzdWx0QW5kRXJyb3I+KHt9KTtcblxuICAgIHRyeSB7XG4gICAgICAvLyB0aGlzLmRlY29kZUZyb21JbnB1dFZpZGVvRGV2aWNlQ29udGludW91c2x5KGRldmljZUlkLCB2aWRlb1NvdXJjZSwgKHJlc3VsdCwgZXJyb3IpID0+IHNjYW4kLm5leHQoeyByZXN1bHQsIGVycm9yIH0pKTtcbiAgICAgIHRoaXMuZ2V0U3RyZWFtRm9yRGV2aWNlKHsgZGV2aWNlSWQgfSlcbiAgICAgICAgLnRoZW4oc3RyZWFtID0+IHRoaXMuYXR0YWNoU3RyZWFtVG9WaWRlb0FuZENoZWNrVG9yY2goc3RyZWFtLCB2aWRlb1NvdXJjZSkpXG4gICAgICAgIC50aGVuKHZpZGVvRWxlbWVudCA9PiB0aGlzLmRlY29kZU9uU3ViamVjdChzY2FuJCwgdmlkZW9FbGVtZW50LCB0aGlzLnRpbWVCZXR3ZWVuU2NhbnNNaWxsaXMpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzY2FuJC5lcnJvcihlKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zZXRTY2FuU3RyZWFtKHNjYW4kKTtcblxuICAgIC8vIEB0b2RvIEZpbmQgYSB3YXkgdG8gZW1pdCBhIGNvbXBsZXRlIGV2ZW50IG9uIHRoZSBzY2FuIHN0cmVhbSBvbmNlIGl0J3MgZmluaXNoZWQuXG5cbiAgICByZXR1cm4gc2NhbiQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbWVkaWEgc3RyZWFtIGZvciBjZXJ0YWluIGRldmljZS5cbiAgICogRmFsbHMgYmFjayB0byBhbnkgYXZhaWxhYmxlIGRldmljZSBpZiBubyBgZGV2aWNlSWRgIGlzIGRlZmluZWQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0U3RyZWFtRm9yRGV2aWNlKHsgZGV2aWNlSWQgfTogUGFydGlhbDxNZWRpYURldmljZUluZm8+KTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIGNvbnN0IGNvbnN0cmFpbnRzID0gdGhpcy5nZXRVc2VyTWVkaWFDb25zdHJhaW50cyhkZXZpY2VJZCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHMpO1xuICAgIHJldHVybiBzdHJlYW07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBtZWRpYSBzdGVyYW0gY29uc3RyYWludHMgZm9yIGNlcnRhaW4gYGRldmljZUlkYC5cbiAgICogRmFsbHMgYmFjayB0byBhbnkgZW52aXJvbm1lbnQgYXZhaWxhYmxlIGRldmljZSBpZiBubyBgZGV2aWNlSWRgIGlzIGRlZmluZWQuXG4gICAqL1xuICBwdWJsaWMgZ2V0VXNlck1lZGlhQ29uc3RyYWludHMoZGV2aWNlSWQ6IHN0cmluZyk6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMge1xuXG4gICAgY29uc3QgdmlkZW8gPSB0eXBlb2YgZGV2aWNlSWQgPT09ICd1bmRlZmluZWQnXG4gICAgICA/IHsgZmFjaW5nTW9kZTogeyBleGFjdDogJ2Vudmlyb25tZW50JyB9IH1cbiAgICAgIDogeyBkZXZpY2VJZDogeyBleGFjdDogZGV2aWNlSWQgfSB9O1xuXG4gICAgY29uc3QgY29uc3RyYWludHM6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMgPSB7IHZpZGVvIH07XG5cbiAgICByZXR1cm4gY29uc3RyYWludHM7XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlcyBhbmQgZGlzYWJsZXMgdGhlIGRldmljZSB0b3JjaC5cbiAgICovXG4gIHB1YmxpYyBzZXRUb3JjaChvbjogYm9vbGVhbik6IHZvaWQge1xuXG4gICAgaWYgKCF0aGlzLl9pc1RvcmNoQXZhaWxhYmxlLnZhbHVlKSB7XG4gICAgICAvLyBjb21wYXRpYmlsaXR5IG5vdCBjaGVja2VkIHlldFxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYWNrcyA9IHRoaXMuZ2V0VmlkZW9UcmFja3ModGhpcy5zdHJlYW0pO1xuXG4gICAgaWYgKG9uKSB7XG4gICAgICB0aGlzLmFwcGx5VG9yY2hPblRyYWNrcyh0cmFja3MsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFwcGx5VG9yY2hPblRyYWNrcyh0cmFja3MsIGZhbHNlKTtcbiAgICAgIC8vIEB0b2RvIGNoZWNrIHBvc3NpYmlsaXR5IHRvIGRpc2FibGUgdG9yY2ggd2l0aG91dCByZXN0YXJ0XG4gICAgICB0aGlzLnJlc3RhcnQoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSB0b3JjaCBjb21wYXRpYmlsaXR5IHN0YXRlIGFuZCBhdHRhY2hzIHRoZSBzdHJlYW0gdG8gdGhlIHByZXZpZXcgZWxlbWVudC5cbiAgICovXG4gIHByaXZhdGUgYXR0YWNoU3RyZWFtVG9WaWRlb0FuZENoZWNrVG9yY2goc3RyZWFtOiBNZWRpYVN0cmVhbSwgdmlkZW9Tb3VyY2U6IEhUTUxWaWRlb0VsZW1lbnQpOiBQcm9taXNlPEhUTUxWaWRlb0VsZW1lbnQ+IHtcbiAgICB0aGlzLnVwZGF0ZVRvcmNoQ29tcGF0aWJpbGl0eShzdHJlYW0pO1xuICAgIHJldHVybiB0aGlzLmF0dGFjaFN0cmVhbVRvVmlkZW8oc3RyZWFtLCB2aWRlb1NvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBzdHJlYW0gc3VwcG9ydHMgdG9yY2ggY29udHJvbC5cbiAgICpcbiAgICogQHBhcmFtIHN0cmVhbSBUaGUgbWVkaWEgc3RyZWFtIHVzZWQgdG8gY2hlY2suXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHVwZGF0ZVRvcmNoQ29tcGF0aWJpbGl0eShzdHJlYW06IE1lZGlhU3RyZWFtKTogUHJvbWlzZTx2b2lkPiB7XG5cbiAgICBjb25zdCB0cmFja3MgPSB0aGlzLmdldFZpZGVvVHJhY2tzKHN0cmVhbSk7XG5cbiAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRyYWNrcykge1xuICAgICAgaWYgKGF3YWl0IHRoaXMuaXNUb3JjaENvbXBhdGlibGUodHJhY2spKSB7XG4gICAgICAgIHRoaXMuX2lzVG9yY2hBdmFpbGFibGUubmV4dCh0cnVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBzdHJlYW0gVGhlIHZpZGVvIHN0cmVhbSB3aGVyZSB0aGUgdHJhY2tzIGdvbm5hIGJlIGV4dHJhY3RlZCBmcm9tLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRWaWRlb1RyYWNrcyhzdHJlYW06IE1lZGlhU3RyZWFtKSB7XG4gICAgbGV0IHRyYWNrcyA9IFtdO1xuICAgIHRyeSB7XG4gICAgICB0cmFja3MgPSBzdHJlYW0uZ2V0VmlkZW9UcmFja3MoKTtcbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICByZXR1cm4gdHJhY2tzIHx8IFtdO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gdHJhY2sgVGhlIG1lZGlhIHN0cmVhbSB0cmFjayB0aGF0IHdpbGwgYmUgY2hlY2tlZCBmb3IgY29tcGF0aWJpbGl0eS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaXNUb3JjaENvbXBhdGlibGUodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spIHtcblxuICAgIGxldCBjb21wYXRpYmxlID0gZmFsc2U7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgaW1hZ2VDYXB0dXJlID0gbmV3IEltYWdlQ2FwdHVyZSh0cmFjayk7XG4gICAgICBjb25zdCBjYXBhYmlsaXRpZXMgPSBhd2FpdCBpbWFnZUNhcHR1cmUuZ2V0UGhvdG9DYXBhYmlsaXRpZXMoKTtcbiAgICAgIGNvbXBhdGlibGUgPSAhIWNhcGFiaWxpdGllc1sndG9yY2gnXSB8fCAoJ2ZpbGxMaWdodE1vZGUnIGluIGNhcGFiaWxpdGllcyAmJiBjYXBhYmlsaXRpZXMuZmlsbExpZ2h0TW9kZS5sZW5ndGggIT09IDApO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgIHJldHVybiBjb21wYXRpYmxlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBseSB0aGUgdG9yY2ggc2V0dGluZyBpbiBhbGwgcmVjZWl2ZWQgdHJhY2tzLlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseVRvcmNoT25UcmFja3ModHJhY2tzOiBNZWRpYVN0cmVhbVRyYWNrW10sIHN0YXRlOiBib29sZWFuKSB7XG4gICAgdHJhY2tzLmZvckVhY2godHJhY2sgPT4gdHJhY2suYXBwbHlDb25zdHJhaW50cyh7XG4gICAgICBhZHZhbmNlZDogWzxhbnk+eyB0b3JjaDogc3RhdGUsIGZpbGxMaWdodE1vZGU6IHN0YXRlID8gJ3RvcmNoJyA6ICdub25lJyB9XVxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3JyZWN0bHkgc2V0cyBhIG5ldyBzY2FuU3RyZWFtIHZhbHVlLlxuICAgKi9cbiAgcHJpdmF0ZSBfc2V0U2NhblN0cmVhbShzY2FuJDogQmVoYXZpb3JTdWJqZWN0PFJlc3VsdEFuZEVycm9yPik6IHZvaWQge1xuICAgIC8vIGNsZWFucyBvbGQgc3RyZWFtXG4gICAgdGhpcy5fY2xlYW5TY2FuU3RyZWFtKCk7XG4gICAgLy8gc2V0cyBuZXcgc3RyZWFtXG4gICAgdGhpcy5zY2FuU3RyZWFtID0gc2NhbiQ7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW5zIGFueSBvbGQgc2NhbiBzdHJlYW0gdmFsdWUuXG4gICAqL1xuICBwcml2YXRlIF9jbGVhblNjYW5TdHJlYW0oKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5zY2FuU3RyZWFtICYmICF0aGlzLnNjYW5TdHJlYW0uaXNTdG9wcGVkKSB7XG4gICAgICB0aGlzLnNjYW5TdHJlYW0uY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICB0aGlzLnNjYW5TdHJlYW0gPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY29kZXMgdmFsdWVzIGluIGEgc3RyZWFtIHdpdGggZGVsYXlzIGJldHdlZW4gc2NhbnMuXG4gICAqXG4gICAqIEBwYXJhbSBzY2FuJCBUaGUgc3ViamVjdCB0byByZWNlaXZlIHRoZSB2YWx1ZXMuXG4gICAqIEBwYXJhbSB2aWRlb0VsZW1lbnQgVGhlIHZpZGVvIGVsZW1lbnQgdGhlIGRlY29kZSB3aWxsIGJlIGFwcGxpZWQuXG4gICAqIEBwYXJhbSBkZWxheSBUaGUgZGVsYXkgYmV0d2VlbiBkZWNvZGUgcmVzdWx0cy5cbiAgICovXG4gIHByaXZhdGUgZGVjb2RlT25TdWJqZWN0KHNjYW4kOiBCZWhhdmlvclN1YmplY3Q8UmVzdWx0QW5kRXJyb3I+LCB2aWRlb0VsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQsIGRlbGF5OiBudW1iZXIpOiB2b2lkIHtcblxuICAgIC8vIHN0b3BzIGxvb3BcbiAgICBpZiAoc2NhbiQuaXNTdG9wcGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdDogUmVzdWx0O1xuXG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IHRoaXMuZGVjb2RlKHZpZGVvRWxlbWVudCk7XG4gICAgICBzY2FuJC5uZXh0KHsgcmVzdWx0IH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBzdHJlYW0gY2Fubm90IHN0b3Agb24gZmFpbHMuXG4gICAgICBpZiAoXG4gICAgICAgICFlcnJvciB8fFxuICAgICAgICAvLyBzY2FuIEZhaWx1cmUgLSBmb3VuZCBub3RoaW5nLCBubyBlcnJvclxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIE5vdEZvdW5kRXhjZXB0aW9uIHx8XG4gICAgICAgIC8vIHNjYW4gRXJyb3IgLSBmb3VuZCB0aGUgUVIgYnV0IGdvdCBlcnJvciBvbiBkZWNvZGluZ1xuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIENoZWNrc3VtRXhjZXB0aW9uIHx8XG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRm9ybWF0RXhjZXB0aW9uXG4gICAgICApIHtcbiAgICAgICAgc2NhbiQubmV4dCh7IGVycm9yIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2NhbiQuZXJyb3IoZXJyb3IpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBjb25zdCB0aW1lb3V0ID0gIXJlc3VsdCA/IDAgOiBkZWxheTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5kZWNvZGVPblN1YmplY3Qoc2NhbiQsIHZpZGVvRWxlbWVudCwgZGVsYXkpLCB0aW1lb3V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzdGFydHMgdGhlIHNjYW5uZXIuXG4gICAqL1xuICBwcml2YXRlIHJlc3RhcnQoKTogT2JzZXJ2YWJsZTxSZXN1bHRBbmRFcnJvcj4ge1xuICAgIC8vIHJlc2V0XG4gICAgLy8gc3RhcnRcbiAgICByZXR1cm4gdGhpcy5jb250aW51b3VzRGVjb2RlRnJvbUlucHV0VmlkZW9EZXZpY2UodGhpcy5kZXZpY2VJZCwgdGhpcy52aWRlb0VsZW1lbnQpO1xuICB9XG5cbn1cbiJdfQ==