UNPKG

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
/** * @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