moh-common-lib
Version:
A library of Angular components, services, and styles for B.C. Government Ministry of Health (MoH).
292 lines (291 loc) • 24.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, Input, Output, EventEmitter, HostListener, forwardRef } from '@angular/core';
import { Base } from '../../models/base';
import { ControlContainer, NgForm } from '@angular/forms';
import * as zxcvbn_ from 'zxcvbn';
// Awkward necessary workaround due to bug in build tools
// https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207
/** @type {?} */
var zxcvbn = zxcvbn_;
/**
* Interface for passing in error messages
* Example:
* errorMessages = {
* required: this.componentLabel + ' is required.',
* minLength: this.componentLabel + ' must be ' + this.minLen + ' characters.',
* criteria: this.componentLabel + ' does not meet password criteria.'
* }
* @record
*/
export function PasswordErrorMsg() { }
if (false) {
/** @type {?|undefined} */
PasswordErrorMsg.prototype.required;
/** @type {?|undefined} */
PasswordErrorMsg.prototype.minLength;
/** @type {?|undefined} */
PasswordErrorMsg.prototype.criteria;
}
/**
* PasswordComponent is a text input for a user's password. It includes:
*
* - A password strength bar
* - Minimum length validations
*
* Note - if your application has requirements to check things like username is not
* present in password, we recommend doing this in the (passwordChange) callback.
*
* \@example
* <common-password componentLabel="{{newPwdLabel}}"
* [showPasswordStrength]="true"
* [minLen]="pwdMinLen"
* [pwdCriteria]="pwdValidChars"
* [password]="data.password"
* (passwordChange)="setNewPassword($event)"></common-password>
*
* @export
*/
var PasswordComponent = /** @class */ (function (_super) {
tslib_1.__extends(PasswordComponent, _super);
function PasswordComponent() {
var _this = _super.call(this) || this;
// Inputs for the component
_this.label = 'Password';
_this.isRequired = true;
_this.isDisabled = false;
_this.minLen = '8';
_this.maxLen = '32';
_this.showPasswordStrength = false;
_this.objectID = 'password_' + _this.objectId;
// Output from the component
_this.passwordChange = new EventEmitter();
_this.blurEvent = new EventEmitter();
// Flag for the fa-eye to show or hide password
_this.hideValue = true;
_this.strengthPercentage = 0;
// default messages
_this.requiredMsgSeg = ' is required.';
_this.minLenMsgSeg1 = ' must be at least ';
_this.minLenMsgSeg2 = ' characters in length.';
_this.criteriaMsg = ' contains invalid characters.';
return _this;
}
/**
* @return {?}
*/
PasswordComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
// Set default messages
this.errMsg = {
required: this.label + this.requiredMsgSeg,
minLength: this.label + this.minLenMsgSeg1 + this.minLen + this.minLenMsgSeg2,
criteria: this.label + this.criteriaMsg
};
// Replace default message if provided
if (this.errorMessages) {
if (this.errorMessages.required) {
this.errMsg.required = this.errorMessages.required;
}
if (this.errorMessages.minLength) {
this.errMsg.minLength = this.errorMessages.minLength;
}
if (this.errorMessages.criteria) {
this.errMsg.criteria = this.errorMessages.criteria;
}
}
};
/**
* @param {?} changes
* @return {?}
*/
PasswordComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes.password && this.password) {
// Check strength of password
this.pswdStrength = this.getPasswordStrength(this.password);
this.strengthPercentage = ((this.pswdStrength + 1) / 5) * 100;
}
};
/**
* Passes the value entered back to the calling component
* @param password value the was entered by
*/
/**
* Passes the value entered back to the calling component
* @param {?} password value the was entered by
* @return {?}
*/
PasswordComponent.prototype.setPassword = /**
* Passes the value entered back to the calling component
* @param {?} password value the was entered by
* @return {?}
*/
function (password) {
this.passwordChange.emit(password);
};
/**
* @param {?} $event
* @return {?}
*/
PasswordComponent.prototype.onInputBlur = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
this.blurEvent.emit(event);
};
// Prevent user from pasting data into the text box
// Prevent user from pasting data into the text box
/**
* @param {?} event
* @return {?}
*/
PasswordComponent.prototype.onPaste =
// Prevent user from pasting data into the text box
/**
* @param {?} event
* @return {?}
*/
function (event) {
return false;
};
/**
* Get the strength of the password
* 0 = too guessable: risky password. (guesses < 10^3)
* 1 = very guessable: protection from throttled online attacks. (guesses < 10^6)
* 2 = somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8)
* 3 = safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10)
* 4 = very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10)
*
* https://github.com/dropbox/zxcvbn
*/
/**
* Get the strength of the password
* 0 = too guessable: risky password. (guesses < 10^3)
* 1 = very guessable: protection from throttled online attacks. (guesses < 10^6)
* 2 = somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8)
* 3 = safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10)
* 4 = very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10)
*
* https://github.com/dropbox/zxcvbn
* @private
* @param {?} password
* @return {?}
*/
PasswordComponent.prototype.getPasswordStrength = /**
* Get the strength of the password
* 0 = too guessable: risky password. (guesses < 10^3)
* 1 = very guessable: protection from throttled online attacks. (guesses < 10^6)
* 2 = somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8)
* 3 = safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10)
* 4 = very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10)
*
* https://github.com/dropbox/zxcvbn
* @private
* @param {?} password
* @return {?}
*/
function (password) {
// Password strength feedback
/** @type {?} */
var pswdFeedback = zxcvbn(password);
return pswdFeedback.score;
};
PasswordComponent.decorators = [
{ type: Component, args: [{
selector: 'common-password',
template: "<label class=\"control-label\" for=\"{{objectID}}\">{{label}}</label>\r\n<input #pswdRef=\"ngModel\"\r\n type=\"{{hideValue? 'password': 'text'}}\"\r\n class=\"form-control password-field\"\r\n name=\"{{objectID}}\"\r\n id=\"{{objectID}}\"\r\n [ngModel]=\"password\"\r\n (ngModelChange)=\"setPassword($event)\"\r\n (blur)=\"onInputBlur($event)\"\r\n [pattern]=\"pwdCriteria\"\r\n [required]=\"isRequired\"\r\n [minlength]=\"minLen\"\r\n [maxlength]=\"maxLen\"\r\n [disabled]=\"isDisabled\"\r\n autocomplete=\"off\"/>\r\n<span class=\"fa fa-fw {{hideValue? 'fa-eye' : 'fa-eye-slash'}} password-field-icon\"\r\n (click)='hideValue = !hideValue'></span>\r\n<div *ngIf='password && showPasswordStrength'>\r\n<!-- The progress bar -->\r\n <div class=\"progress password-strength-bar\" >\r\n <div class=\"progress-bar {{pswdStrength >= 4? 'bg-success' : (pswdStrength >= 3? 'bg-warning' : 'bg-danger')}}\"\r\n role=\"progressbar\"\r\n [style.width]='strengthPercentage + \"%\"'\r\n [attr.aria-valuenow]=\"strengthPercentage\"\r\n aria-valuemin=\"0\"\r\n aria-valuemax=\"100\">\r\n </div>\r\n </div>\r\n <span class=\"password-progress-label {{pswdStrength >= 4? 'text-success' : (pswdStrength >= 3? 'text-warning' : 'text-danger')}}\"></span>\r\n</div>\r\n<!-- Error messages for component -->\r\n<div *ngIf=\"!pswdRef.disabled && (pswdRef.touched || pswdRef.dirty)\"\r\n role=\"alert\"\r\n class='error-container'\r\n aria-live=\"assertive\">\r\n <div class=\"text-danger\" *ngIf=\"pswdRef?.errors?.required\">\r\n {{errMsg.required}}\r\n </div>\r\n <div class=\"text-danger\" *ngIf=\"pswdRef?.errors?.minlength\">\r\n {{errMsg.minLength}}\r\n </div>\r\n <div class=\"text-danger\" *ngIf=\"pswdRef?.errors?.pattern && !pswdRef?.errors?.minlength\">\r\n {{errMsg.criteria}}\r\n </div>\r\n</div>\r\n\r\n",
/* Re-use the same ngForm that it's parent is using. The component will show
* up in its parents `this.form`, and will auto-update `this.form.valid`
*/
viewProviders: [{ provide: ControlContainer, useExisting: forwardRef((/**
* @return {?}
*/
function () { return NgForm; })) }],
styles: [".password-field-icon{float:right;margin-left:-25px;margin-top:-25px;margin-right:.5rem;position:relative;z-index:2}.password-field{padding-right:2rem}.password-strength-bar{min-width:0;max-width:75%;height:.5rem;margin-top:1em}.password-progress-label{float:right;margin-left:-15px;margin-top:-15px;position:relative;z-index:2}.password-strength-bar+.text-success::after{content:'Good'}.password-strength-bar+.text-warning::after{content:'OK'}.password-strength-bar+.text-danger::after{content:'Bad'}input{width:100%}input[type=password]::-ms-clear,input[type=password]::-ms-reveal{display:none}"]
}] }
];
/** @nocollapse */
PasswordComponent.ctorParameters = function () { return []; };
PasswordComponent.propDecorators = {
label: [{ type: Input }],
isRequired: [{ type: Input }],
isDisabled: [{ type: Input }],
password: [{ type: Input }],
pwdCriteria: [{ type: Input }],
minLen: [{ type: Input }],
maxLen: [{ type: Input }],
errorMessages: [{ type: Input }],
showPasswordStrength: [{ type: Input }],
objectID: [{ type: Input }],
passwordChange: [{ type: Output }],
blurEvent: [{ type: Output }],
onPaste: [{ type: HostListener, args: ['document:paste', ['$event'],] }]
};
return PasswordComponent;
}(Base));
export { PasswordComponent };
if (false) {
/** @type {?} */
PasswordComponent.prototype.label;
/** @type {?} */
PasswordComponent.prototype.isRequired;
/** @type {?} */
PasswordComponent.prototype.isDisabled;
/** @type {?} */
PasswordComponent.prototype.password;
/** @type {?} */
PasswordComponent.prototype.pwdCriteria;
/** @type {?} */
PasswordComponent.prototype.minLen;
/** @type {?} */
PasswordComponent.prototype.maxLen;
/** @type {?} */
PasswordComponent.prototype.errorMessages;
/** @type {?} */
PasswordComponent.prototype.showPasswordStrength;
/** @type {?} */
PasswordComponent.prototype.objectID;
/** @type {?} */
PasswordComponent.prototype.passwordChange;
/** @type {?} */
PasswordComponent.prototype.blurEvent;
/** @type {?} */
PasswordComponent.prototype.hideValue;
/** @type {?} */
PasswordComponent.prototype.pswdStrength;
/** @type {?} */
PasswordComponent.prototype.strengthPercentage;
/** @type {?} */
PasswordComponent.prototype.errMsg;
/**
* @type {?}
* @private
*/
PasswordComponent.prototype.requiredMsgSeg;
/**
* @type {?}
* @private
*/
PasswordComponent.prototype.minLenMsgSeg1;
/**
* @type {?}
* @private
*/
PasswordComponent.prototype.minLenMsgSeg2;
/**
* @type {?}
* @private
*/
PasswordComponent.prototype.criteriaMsg;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFzc3dvcmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbW9oLWNvbW1vbi1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9wYXNzd29yZC9wYXNzd29yZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBYSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDcEgsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRCxPQUFPLEtBQUssT0FBTyxNQUFNLFFBQVEsQ0FBQzs7OztJQUc1QixNQUFNLEdBQUcsT0FBTzs7Ozs7Ozs7Ozs7QUFldEIsc0NBSUM7OztJQUhDLG9DQUFrQjs7SUFDbEIscUNBQW1COztJQUNuQixvQ0FBa0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFCcEI7SUFTdUMsNkNBQUk7SUFpQ3pDO1FBQUEsWUFDRSxpQkFBTyxTQUNSOztRQWhDUSxXQUFLLEdBQVcsVUFBVSxDQUFDO1FBQzNCLGdCQUFVLEdBQVksSUFBSSxDQUFDO1FBQzNCLGdCQUFVLEdBQVksS0FBSyxDQUFDO1FBRzVCLFlBQU0sR0FBWSxHQUFHLENBQUM7UUFDdEIsWUFBTSxHQUFZLElBQUksQ0FBQztRQUV2QiwwQkFBb0IsR0FBWSxLQUFLLENBQUM7UUFDdEMsY0FBUSxHQUFXLFdBQVcsR0FBRyxLQUFJLENBQUMsUUFBUSxDQUFDOztRQUk5QyxvQkFBYyxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ2xFLGVBQVMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDOztRQUdsQyxlQUFTLEdBQUcsSUFBSSxDQUFDO1FBRWpCLHdCQUFrQixHQUFHLENBQUMsQ0FBQzs7UUFLdEIsb0JBQWMsR0FB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QUNOLE1BQU07MEJBb0VOLFlBQVksU0FBRSxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7SUFxQjdDLHdCQUFDO0NBQUEsQUFuSEQsQ0FTdUMsSUFBSSxHQTBHMUM7U0ExR1ksaUJBQWlCOzs7SUFHNUIsa0NBQW9DOztJQUNwQyx1Q0FBb0M7O0lBQ3BDLHVDQUFxQzs7SUFDckMscUNBQTBCOztJQUMxQix3Q0FBc0M7O0lBQ3RDLG1DQUErQjs7SUFDL0IsbUNBQWdDOztJQUNoQywwQ0FBeUM7O0lBQ3pDLGlEQUErQzs7SUFDL0MscUNBQXdEOztJQUl4RCwyQ0FBNEU7O0lBQzVFLHNDQUF5Qzs7SUFHekMsc0NBQXdCOztJQUN4Qix5Q0FBNEI7O0lBQzVCLCtDQUE4Qjs7SUFFOUIsbUNBQWdDOzs7OztJQUdoQywyQ0FBaUQ7Ozs7O0lBQ2pELDBDQUFxRDs7Ozs7SUFDckQsMENBQXlEOzs7OztJQUN6RCx3Q0FBOEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIE9uQ2hhbmdlcywgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Jhc2UnO1xyXG5pbXBvcnQgeyBDb250cm9sQ29udGFpbmVyLCBOZ0Zvcm0gfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCAqIGFzIHp4Y3Zibl8gZnJvbSAnenhjdmJuJztcclxuLy8gQXdrd2FyZCBuZWNlc3Nhcnkgd29ya2Fyb3VuZCBkdWUgdG8gYnVnIGluIGJ1aWxkIHRvb2xzXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qdmFuZGVtby9nZW5lcmF0b3ItYW5ndWxhcjItbGlicmFyeS9pc3N1ZXMvMjIxI2lzc3VlY29tbWVudC0zNTU5NDUyMDdcclxuY29uc3QgenhjdmJuID0genhjdmJuXztcclxuXHJcblxyXG4vKipcclxuICogVE9ETzogIENvbnZlcnQgdG8gY3VzdG9tIGZvcm0gY29udHJvbCAtIHJlbW92ZSBuZ0Zvcm1cclxuICovXHJcbi8qKlxyXG4gKiBJbnRlcmZhY2UgZm9yIHBhc3NpbmcgaW4gZXJyb3IgbWVzc2FnZXNcclxuICogRXhhbXBsZTpcclxuICogIGVycm9yTWVzc2FnZXMgPSB7XHJcbiAqICAgICAgIHJlcXVpcmVkOiB0aGlzLmNvbXBvbmVudExhYmVsICsgJyBpcyByZXF1aXJlZC4nLFxyXG4gKiAgICAgICBtaW5MZW5ndGg6IHRoaXMuY29tcG9uZW50TGFiZWwgKyAnIG11c3QgYmUgJyArIHRoaXMubWluTGVuICsgJyBjaGFyYWN0ZXJzLicsXHJcbiAqICAgICAgIGNyaXRlcmlhOiB0aGlzLmNvbXBvbmVudExhYmVsICsgJyBkb2VzIG5vdCBtZWV0IHBhc3N3b3JkIGNyaXRlcmlhLidcclxuICogICAgIH1cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgUGFzc3dvcmRFcnJvck1zZyB7XHJcbiAgcmVxdWlyZWQ/OiBzdHJpbmc7XHJcbiAgbWluTGVuZ3RoPzogc3RyaW5nO1xyXG4gIGNyaXRlcmlhPzogc3RyaW5nO1xyXG59XHJcbi8qKlxyXG4gKiBQYXNzd29yZENvbXBvbmVudCBpcyBhIHRleHQgaW5wdXQgZm9yIGEgdXNlcidzIHBhc3N3b3JkLiBJdCBpbmNsdWRlczpcclxuICpcclxuICogLSBBIHBhc3N3b3JkIHN0cmVuZ3RoIGJhclxyXG4gKiAtIE1pbmltdW0gbGVuZ3RoIHZhbGlkYXRpb25zXHJcbiAqXHJcbiAqIE5vdGUgLSBpZiB5b3VyIGFwcGxpY2F0aW9uIGhhcyByZXF1aXJlbWVudHMgdG8gY2hlY2sgdGhpbmdzIGxpa2UgdXNlcm5hbWUgaXMgbm90XHJcbiAqIHByZXNlbnQgaW4gcGFzc3dvcmQsIHdlIHJlY29tbWVuZCBkb2luZyB0aGlzIGluIHRoZSAocGFzc3dvcmRDaGFuZ2UpIGNhbGxiYWNrLlxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiAgICAgICA8Y29tbW9uLXBhc3N3b3JkIGNvbXBvbmVudExhYmVsPVwie3tuZXdQd2RMYWJlbH19XCJcclxuICogICAgICAgICAgICAgICAgICAgICAgW3Nob3dQYXNzd29yZFN0cmVuZ3RoXT1cInRydWVcIlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICBbbWluTGVuXT1cInB3ZE1pbkxlblwiXHJcbiAqICAgICAgICAgICAgICAgICAgICAgIFtwd2RDcml0ZXJpYV09XCJwd2RWYWxpZENoYXJzXCJcclxuICogICAgICAgICAgICAgICAgICAgICAgW3Bhc3N3b3JkXT1cImRhdGEucGFzc3dvcmRcIlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAocGFzc3dvcmRDaGFuZ2UpPVwic2V0TmV3UGFzc3dvcmQoJGV2ZW50KVwiPjwvY29tbW9uLXBhc3N3b3JkPlxyXG4gKlxyXG4gKiBAZXhwb3J0XHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2NvbW1vbi1wYXNzd29yZCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3Bhc3N3b3JkLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9wYXNzd29yZC5jb21wb25lbnQuc2NzcyddLFxyXG4gIC8qIFJlLXVzZSB0aGUgc2FtZSBuZ0Zvcm0gdGhhdCBpdCdzIHBhcmVudCBpcyB1c2luZy4gVGhlIGNvbXBvbmVudCB3aWxsIHNob3dcclxuICAgKiB1cCBpbiBpdHMgcGFyZW50cyBgdGhpcy5mb3JtYCwgYW5kIHdpbGwgYXV0by11cGRhdGUgYHRoaXMuZm9ybS52YWxpZGBcclxuICAgKi9cclxuICB2aWV3UHJvdmlkZXJzOiBbIHsgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lciwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmdGb3JtICkgfSBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQYXNzd29yZENvbXBvbmVudCBleHRlbmRzIEJhc2UgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XHJcblxyXG4gIC8vIElucHV0cyBmb3IgdGhlIGNvbXBvbmVudFxyXG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSAnUGFzc3dvcmQnO1xyXG4gIEBJbnB1dCgpIGlzUmVxdWlyZWQ6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGlzRGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBwYXNzd29yZDogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIHB3ZENyaXRlcmlhOiBzdHJpbmcgfCBSZWdFeHA7XHJcbiAgQElucHV0KCkgbWluTGVuOiBzdHJpbmcgID0gJzgnO1xyXG4gIEBJbnB1dCgpIG1heExlbjogc3RyaW5nICA9ICczMic7XHJcbiAgQElucHV0KCkgZXJyb3JNZXNzYWdlczogUGFzc3dvcmRFcnJvck1zZztcclxuICBASW5wdXQoKSBzaG93UGFzc3dvcmRTdHJlbmd0aDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIG9iamVjdElEOiBzdHJpbmcgPSAncGFzc3dvcmRfJyArIHRoaXMub2JqZWN0SWQ7XHJcblxyXG5cclxuICAvLyBPdXRwdXQgZnJvbSB0aGUgY29tcG9uZW50XHJcbiAgQE91dHB1dCgpIHBhc3N3b3JkQ2hhbmdlOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG4gIEBPdXRwdXQoKSBibHVyRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIC8vIEZsYWcgZm9yIHRoZSBmYS1leWUgdG8gc2hvdyBvciBoaWRlIHBhc3N3b3JkXHJcbiAgcHVibGljIGhpZGVWYWx1ZSA9IHRydWU7XHJcbiAgcHVibGljIHBzd2RTdHJlbmd0aDogbnVtYmVyO1xyXG4gIHB1YmxpYyBzdHJlbmd0aFBlcmNlbnRhZ2UgPSAwO1xyXG5cclxuICBwdWJsaWMgZXJyTXNnOiBQYXNzd29yZEVycm9yTXNnO1xyXG5cclxuICAvLyBkZWZhdWx0IG1lc3NhZ2VzXHJcbiAgcHJpdmF0ZSByZXF1aXJlZE1zZ1NlZzogc3RyaW5nID0gJyBpcyByZXF1aXJlZC4nO1xyXG4gIHByaXZhdGUgbWluTGVuTXNnU2VnMTogc3RyaW5nID0gJyBtdXN0IGJlIGF0IGxlYXN0ICc7XHJcbiAgcHJpdmF0ZSBtaW5MZW5Nc2dTZWcyOiBzdHJpbmcgPSAnIGNoYXJhY3RlcnMgaW4gbGVuZ3RoLic7XHJcbiAgcHJpdmF0ZSBjcml0ZXJpYU1zZzogc3RyaW5nID0gJyBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMuJztcclxuXHJcblxyXG4gIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgc3VwZXIoKTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG5cclxuICAgIC8vIFNldCBkZWZhdWx0IG1lc3NhZ2VzXHJcbiAgICB0aGlzLmVyck1zZyA9ICAgIHtcclxuICAgICAgcmVxdWlyZWQ6IHRoaXMubGFiZWwgKyB0aGlzLnJlcXVpcmVkTXNnU2VnLFxyXG4gICAgICBtaW5MZW5ndGg6IHRoaXMubGFiZWwgKyB0aGlzLm1pbkxlbk1zZ1NlZzEgKyB0aGlzLm1pbkxlbiArIHRoaXMubWluTGVuTXNnU2VnMixcclxuICAgICAgY3JpdGVyaWE6IHRoaXMubGFiZWwgKyB0aGlzLmNyaXRlcmlhTXNnXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIFJlcGxhY2UgZGVmYXVsdCBtZXNzYWdlIGlmIHByb3ZpZGVkXHJcbiAgICBpZiAoIHRoaXMuZXJyb3JNZXNzYWdlcyApIHtcclxuXHJcbiAgICAgIGlmICggdGhpcy5lcnJvck1lc3NhZ2VzLnJlcXVpcmVkICkge1xyXG4gICAgICAgIHRoaXMuZXJyTXNnLnJlcXVpcmVkID0gdGhpcy5lcnJvck1lc3NhZ2VzLnJlcXVpcmVkO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIHRoaXMuZXJyb3JNZXNzYWdlcy5taW5MZW5ndGggKSB7XHJcbiAgICAgICAgdGhpcy5lcnJNc2cubWluTGVuZ3RoID0gdGhpcy5lcnJvck1lc3NhZ2VzLm1pbkxlbmd0aDtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCB0aGlzLmVycm9yTWVzc2FnZXMuY3JpdGVyaWEgKSB7XHJcbiAgICAgICAgdGhpcy5lcnJNc2cuY3JpdGVyaWEgPSB0aGlzLmVycm9yTWVzc2FnZXMuY3JpdGVyaWE7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXMpIHtcclxuICAgIGlmIChjaGFuZ2VzLnBhc3N3b3JkICYmIHRoaXMucGFzc3dvcmQpIHtcclxuXHJcbiAgICAgIC8vIENoZWNrIHN0cmVuZ3RoIG9mIHBhc3N3b3JkXHJcbiAgICAgIHRoaXMucHN3ZFN0cmVuZ3RoID0gdGhpcy5nZXRQYXNzd29yZFN0cmVuZ3RoKCB0aGlzLnBhc3N3b3JkICk7XHJcbiAgICAgIHRoaXMuc3RyZW5ndGhQZXJjZW50YWdlID0gKCh0aGlzLnBzd2RTdHJlbmd0aCArIDEpIC8gNSApICogMTAwO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUGFzc2VzIHRoZSB2YWx1ZSBlbnRlcmVkIGJhY2sgdG8gdGhlIGNhbGxpbmcgY29tcG9uZW50XHJcbiAgICogQHBhcmFtIHBhc3N3b3JkIHZhbHVlIHRoZSB3YXMgZW50ZXJlZCBieVxyXG4gICAqL1xyXG4gIHNldFBhc3N3b3JkKCBwYXNzd29yZDogc3RyaW5nICkge1xyXG4gICAgdGhpcy5wYXNzd29yZENoYW5nZS5lbWl0KCBwYXNzd29yZCApO1xyXG4gIH1cclxuXHJcbiAgb25JbnB1dEJsdXIoJGV2ZW50KSB7XHJcbiAgICB0aGlzLmJsdXJFdmVudC5lbWl0KCBldmVudCApO1xyXG4gIH1cclxuXHJcbiAgLy8gUHJldmVudCB1c2VyIGZyb20gcGFzdGluZyBkYXRhIGludG8gdGhlIHRleHQgYm94XHJcbiAgQEhvc3RMaXN0ZW5lciggJ2RvY3VtZW50OnBhc3RlJywgWyckZXZlbnQnXSApXHJcbiAgb25QYXN0ZSggZXZlbnQgKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgc3RyZW5ndGggb2YgdGhlIHBhc3N3b3JkXHJcblxyXG4gICAqICAgIDAgPSB0b28gZ3Vlc3NhYmxlOiByaXNreSBwYXNzd29yZC4gKGd1ZXNzZXMgPCAxMF4zKVxyXG4gICAqICAgIDEgPSB2ZXJ5IGd1ZXNzYWJsZTogcHJvdGVjdGlvbiBmcm9tIHRocm90dGxlZCBvbmxpbmUgYXR0YWNrcy4gKGd1ZXNzZXMgPCAxMF42KVxyXG4gICAqICAgIDIgPSBzb21ld2hhdCBndWVzc2FibGU6IHByb3RlY3Rpb24gZnJvbSB1bnRocm90dGxlZCBvbmxpbmUgYXR0YWNrcy4gKGd1ZXNzZXMgPCAxMF44KVxyXG4gICAqICAgIDMgPSBzYWZlbHkgdW5ndWVzc2FibGU6IG1vZGVyYXRlIHByb3RlY3Rpb24gZnJvbSBvZmZsaW5lIHNsb3ctaGFzaCBzY2VuYXJpby4gKGd1ZXNzZXMgPCAxMF4xMClcclxuICAgKiAgICA0ID0gdmVyeSB1bmd1ZXNzYWJsZTogc3Ryb25nIHByb3RlY3Rpb24gZnJvbSBvZmZsaW5lIHNsb3ctaGFzaCBzY2VuYXJpby4gKGd1ZXNzZXMgPj0gMTBeMTApXHJcbiAgICpcclxuICAgKiAgaHR0cHM6Ly9naXRodWIuY29tL2Ryb3Bib3gvenhjdmJuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRQYXNzd29yZFN0cmVuZ3RoKCBwYXNzd29yZDogc3RyaW5nICk6IG51bWJlciB7XHJcbiAgICAvLyBQYXNzd29yZCBzdHJlbmd0aCBmZWVkYmFja1xyXG4gICAgY29uc3QgcHN3ZEZlZWRiYWNrID0genhjdmJuKCBwYXNzd29yZCApO1xyXG4gICAgcmV0dXJuIHBzd2RGZWVkYmFjay5zY29yZTtcclxuICB9XHJcbn1cclxuIl19