UNPKG

moh-common-lib

Version:

A library of Angular components, services, and styles for B.C. Government Ministry of Health (MoH).

507 lines 64.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ElementRef, ViewChild, NgZone, ChangeDetectorRef, Output, Input, EventEmitter, Optional, Self } from '@angular/core'; import { CaptchaDataService } from './captcha-data.service'; import { NgControl } from '@angular/forms'; /** * CAPTCHA can display a "required" error automatically when you programmaically * call `markAllInpusAsTouched()`. (\@see AbstractForm). In order to do this, * you must set: name, ngModel, and required. Otherwise, these fields are * optional. * * \@example * <common-captcha * [nonce]="application.uuid" * [apiBaseUrl]="captchaApiBaseUrl" * (onValidToken)="setToken($event)" * name='captcha' * ngModel * required> * </common-captcha> */ export class CaptchaComponent { /** * @param {?} dataService * @param {?} cd * @param {?} ngZone * @param {?} controlDir */ constructor(dataService, cd, ngZone, controlDir) { this.dataService = dataService; this.cd = cd; this.ngZone = ngZone; this.controlDir = controlDir; // tslint:disable-next-line:no-output-on-prefix this.onValidToken = new EventEmitter(); this.language = 'en'; /** * Http error response for fetching a CAPTCHA image. */ this.errorFetchingImg = null; /** * Http error response for verifying user's answer. */ this.errorVerifyAnswer = null; this.validation = ''; this.audio = ''; this.answer = ''; this.fetchingAudioInProgress = false; this._onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this._onTouched = (/** * @return {?} */ () => { }); // tslint:disable-next-line:member-ordering this.translatedMessages = { playAudio: { en: 'Play Audio', zh: '播放声音', fr: 'Lecture audio', pa: 'ਆਡੀਓ ਚਲਾਓ', }, tryAnotherImg: { en: 'Try another image', zh: '换个图像', fr: 'Essayez une autre image', pa: 'ਕੋਈ ਹੋਰ ਚਿੱਤਰ ਅਜ਼ਮਾਓ', }, userPromptMessage: { en: 'Enter the text you either see in the box or you hear in the audio', zh: '请输入看到或听到的文字', fr: 'Entrez le texte que vous voyez dans la case ou que vous entendez dans le son', pa: 'ਉਹ ਟੈਕਸਟ ਦਾਖਲ ਕਰੋ ਜੋ ਤੁਸੀਂ ਬਕਸੇ ਵਿੱਚ ਦੇਖਦੇ ਹੋ ਜਾਂ ਤੁਸੀਂ ਆਡੀਓ ਵਿੱਚ ਸੁਣਦੇ ਹੋ', }, incorrectAnswer: { en: 'Incorrect answer, please try again.', zh: '答案不对。请重试。', fr: 'Mauvaise réponse, veuillez réessayer.', pa: 'ਗਲਤ ਜਵਾਬ, ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ.', }, successMessage: { en: 'You can submit your application now.', zh: '你现在可以提交申请了。', fr: 'Vous pouvez soumettre votre candidature maintenant.', pa: 'ਤੁਸੀਂ ਆਪਣੀ ਅਰਜ਼ੀ ਹੁਣੇ ਪੇਸ਼ ਕਰ ਸਕਦੇ ਹੋ', }, correct: { en: 'Correct.', zh: '正确。', fr: 'Correct.', pa: 'ਸਹੀ ਕਰੋ', }, loadingImage: { en: 'Loading CAPTCHA image', zh: '正在下载验证码', fr: 'Chargement de l\'image CAPTCHA', pa: 'ਕੈਪਟਚਾ ਚਿੱਤਰ ਲੋਡ ਕਰ ਰਿਹਾ ਹੈ', }, browserNotSupportAudio: { en: 'Your browser does not support the audio element.', zh: '你的浏览器不支持播音', fr: 'Votre navigateur ne supporte pas l\'élément audio.', pa: 'ਤੁਹਾਡਾ ਬ੍ਰਾਉਜ਼ਰ ਆਡੀਓ ਐਲੀਮੈਂਟ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ.', }, verifyingAnswer: { en: 'Verifying your answer...', zh: '正在验证答案...', fr: 'Vérification de votre réponse ...', pa: 'ਤੁਹਾਡਾ ਜਵਾਬ ਤਸਦੀਕ ਕਰ ਰਿਹਾ ਹੈ ...', }, errorRetrievingImg: { en: 'Error happened while retrieving CAPTCHA image. Please {{Click Here}} to try again', zh: '验证码下载错误。请{{点击这里}}重试', fr: 'Une erreur s\'est produite lors de la récupération de l\'image CAPTCHA. S\'il vous plaît {{Cliquez Ici}} pour réessayer', pa: 'ਕੈਪਟਚਾ ਚਿੱਤਰ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਦੇ ਸਮੇਂ ਤਰੁੱਟੀ ਉਤਪੰਨ ਹੋਈ. ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ {{ਇੱਥੇ ਕਲਿਕ ਕਰੋ}}', }, errorVerifyingAnswer: { en: 'Error happened while verifying your answer. Please {{Click Here}} to try again', zh: '验证答案过程发生错误。请{{点击这里}}重试', fr: 'Une erreur s\'est produite lors de la vérification de votre réponse. S\'il vous plaît {{Cliquez Ici}} pour réessayer', pa: 'ਤੁਹਾਡਾ ਜਵਾਬ ਤਸਦੀਕ ਕਰਨ ਵੇਲੇ ਗਲਤੀ ਆਈ ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ {{ਇੱਥੇ ਕਲਿਕ ਕਰੋ}}', }, }; if (controlDir) { controlDir.valueAccessor = this; } } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this._onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this._onTouched = fn; } /** * @param {?} value * @return {?} */ writeValue(value) { this.answer = value; } /** * @return {?} */ onBlur() { this._onTouched(); } /** * @return {?} */ ngOnInit() { this.forceRefresh.bind(this); window['ca.bcgov.captchaRefresh'] = this.publicForceRefresh.bind(this); // if(!this.userPromptMessage){ // this.userPromptMessage = "Enter the text you either see in the box or you hear in the audio"; // } } /** * @return {?} */ ngAfterViewInit() { this.forceRefresh(); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { // when changing language, if audio is empty then no need to refetch if (!changes.language || !this.audio || this.audio.length === 0) { if (!(changes.reloadCaptcha && (true === changes.reloadCaptcha.previousValue || false === changes.reloadCaptcha.previousValue) && (changes.reloadCaptcha.currentValue !== changes.reloadCaptcha.previousValue))) { return; } } this.getNewCaptcha(false); } /** * @return {?} */ forceRefresh() { this.getNewCaptcha(false); this.cd.detectChanges(); } /** * @return {?} */ publicForceRefresh() { this.ngZone.run((/** * @return {?} */ () => this.forceRefresh())); } /** * @param {?} event * @return {?} */ answerChanged(event) { if (this.answer.length < 6) { this.incorrectAnswer = null; } if (this.answer.length === 6) { this._onChange(event); // have response trigger _onChange for custom form control this.state = CAPTCHA_STATE.VERIFYING_ANSWER; this.incorrectAnswer = null; this.dataService.verifyCaptcha(this.apiBaseUrl, this.nonce, this.answer, this.validation).subscribe((/** * @param {?} response * @return {?} */ response => { /** @type {?} */ const payload = response.body; if (this.isValidPayload(payload)) { this.handleVerify(payload); } else { this.state = CAPTCHA_STATE.ERROR_VERIFY; this.errorVerifyAnswer = this.createErrorTextLine(response); } }), (/** * @param {?} error * @return {?} */ (error) => { this.state = CAPTCHA_STATE.ERROR_VERIFY; this.errorVerifyAnswer = this.createErrorTextLine(error); })); } } // Call the backend to see if our answer is correct /** * @private * @param {?} payload * @return {?} */ handleVerify(payload) { // There could be the rare change where an invalid payload response is received. if (payload.valid === true) { this.state = CAPTCHA_STATE.SUCCESS_VERIFY_ANSWER_CORRECT; this.onValidToken.emit(payload.jwt); // this.controlDir.errors.set } else { this.incorrectAnswer = true; this.answer = ''; this.audio = ''; // They failed - try a new one. this.getNewCaptcha(true); } } /** * Case where HTTP 200 response code is received by the payload is incorrect or corrupt. * The occurance of this type of case should be rare. * @private * @param {?} payload * @return {?} */ isValidPayload(payload) { // console.debug('Response payload: %o', payload); if (!payload) { console.error('payload cannot be null or undefined or 0'); return false; } else { /** @type {?} */ const hasValueProp = payload.hasOwnProperty('valid'); if (!hasValueProp) { console.error('payload must have its own property named \'valid\''); return false; } else { return true; } } } /** * @return {?} */ retryFetchCaptcha() { this.state = undefined; /** * wait for 0.5 seond before resubmitting */ setTimeout((/** * @return {?} */ () => { this.getNewCaptcha(false); }), 100); } /** * @return {?} */ playAudio() { if (this.audio && this.audio.length > 0) { this.audioElement.nativeElement.play(); } else { this.fetchAudio(true); } } /** * @private * @param {?=} playImmediately * @return {?} */ fetchAudio(playImmediately = false) { if (!this.fetchingAudioInProgress) { this.fetchingAudioInProgress = true; this.dataService.fetchAudio(this.apiBaseUrl, this.validation, this.language).subscribe((/** * @param {?} response * @return {?} */ (response) => { this.fetchingAudioInProgress = false; this.audio = response.body.audio; this.cd.detectChanges(); if (playImmediately) { this.audioElement.nativeElement.play(); } }), (/** * @param {?} error * @return {?} */ (error) => { this.fetchingAudioInProgress = false; this.cd.detectChanges(); })); } } /** * @param {?} errorCase * @return {?} */ getNewCaptcha(errorCase) { this.state = CAPTCHA_STATE.FETCHING_CAPTCHA_IMG; this.audio = ''; // Reset things if (!errorCase) { // Let them know they failed instead of wiping out the answer area // Contructing this form on page load/reload will have errorCase = false this.incorrectAnswer = null; } this.dataService.fetchData(this.apiBaseUrl, this.nonce).subscribe((/** * @param {?} response * @return {?} */ response => { this.state = CAPTCHA_STATE.SUCCESS_FETCH_IMG; /** @type {?} */ const payload = response.body; this.imageContainer.nativeElement.innerHTML = payload.captcha; this.validation = payload.validation; this.cd.detectChanges(); if (this.eagerFetchAudio === 'true') { this.fetchAudio(); } else { // console.log('Not to fetch audio eagerly'); } }), (/** * @param {?} error * @return {?} */ (error) => { this.state = CAPTCHA_STATE.ERROR_FETCH_IMG; this.errorFetchingImg = this.createErrorTextLine(error); this.cd.detectChanges(); })); } /** * @private * @param {?} error * @return {?} */ createErrorTextLine(error) { /** @type {?} */ let line = 'Error status: ' + error.status; if (error.statusText) { line = line + ', status text: ' + error.statusText; } return line; } } CaptchaComponent.decorators = [ { type: Component, args: [{ selector: 'common-captcha', template: "<div class=\"bcgov-captcha\">\r\n\r\n\r\n <svg class=\"defs\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n <defs>\r\n <symbol id=\"icon-play-def\" viewBox=\"0 0 32 32\">\r\n <path d=\"M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM16 29c-7.18 0-13-5.82-13-13s5.82-13 13-13 13 5.82 13 13-5.82 13-13 13zM12 9l12 7-12 7z\"></path>\r\n </symbol>\r\n\r\n <symbol id=\"icon-loop-def\" viewBox=\"0 0 32 32\">\r\n <path d=\"M27.802 5.197c-2.925-3.194-7.13-5.197-11.803-5.197-8.837 0-16 7.163-16 16h3c0-7.18 5.82-13 13-13 3.844 0 7.298 1.669 9.678 4.322l-4.678 4.678h11v-11l-4.198 4.197z\"></path>\r\n <path d=\"M29 16c0 7.18-5.82 13-13 13-3.844 0-7.298-1.669-9.678-4.322l4.678-4.678h-11v11l4.197-4.197c2.925 3.194 7.13 5.197 11.803 5.197 8.837 0 16-7.163 16-16h-3z\"></path>\r\n </symbol>\r\n\r\n <symbol id=\"icon-check-def\" viewBox=\"0 0 24 24\">\r\n <path d=\"M9 16.172l10.594-10.594 1.406 1.406-12 12-5.578-5.578 1.406-1.406z\"></path>\r\n </symbol>\r\n\r\n <symbol id=\"icon-exclamation-triangle-def\" viewBox=\"0 0 28 28\">\r\n <path d=\"M16 21.484v-2.969c0-0.281-0.219-0.516-0.5-0.516h-3c-0.281 0-0.5 0.234-0.5 0.516v2.969c0 0.281 0.219 0.516 0.5 0.516h3c0.281 0 0.5-0.234 0.5-0.516zM15.969 15.641l0.281-7.172c0-0.094-0.047-0.219-0.156-0.297-0.094-0.078-0.234-0.172-0.375-0.172h-3.437c-0.141 0-0.281 0.094-0.375 0.172-0.109 0.078-0.156 0.234-0.156 0.328l0.266 7.141c0 0.203 0.234 0.359 0.531 0.359h2.891c0.281 0 0.516-0.156 0.531-0.359zM15.75 1.047l12 22c0.344 0.609 0.328 1.359-0.031 1.969s-1.016 0.984-1.719 0.984h-24c-0.703 0-1.359-0.375-1.719-0.984s-0.375-1.359-0.031-1.969l12-22c0.344-0.641 1.016-1.047 1.75-1.047s1.406 0.406 1.75 1.047z\"></path>\r\n </symbol>\r\n\r\n </defs>\r\n </svg>\r\n\r\n\r\n\r\n <form class=\"captcha-form\" #formRef=\"ngForm\">\r\n <div [ngClass]=\"{'has-error': !!incorrectAnswer}\">\r\n <div>\r\n\r\n <div class=\"spinner-box\" *ngIf=\"!state || state === 1\">\r\n <div>\r\n <svg class=\"captcha-spinner\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"xMidYMid\"><g transform=\"rotate(0 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.8888888888888888s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(40 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.7777777777777778s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(80 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.6666666666666666s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(120 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.5555555555555556s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(160 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.4444444444444444s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(200 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.3333333333333333s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(240 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.2222222222222222s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(280 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.1111111111111111s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(320 50 50)\">\r\n <rect x=\"47\" y=\"22\" rx=\"9.4\" ry=\"4.4\" width=\"6\" height=\"16\" fill=\"#1d3f72\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"0s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g></svg>\r\n </div>\r\n <div>\r\n {{translatedMessages.loadingImage[language]}}\r\n </div>\r\n </div>\r\n\r\n <div [ngClass]=\"{'captcha-box-visible': state === 2, 'captcha-box-invisible': state !== 2}\">\r\n <div class=\"captcha-image-and-buttons-container\">\r\n <div #image class=\"captcha-image\"></div>\r\n <audio #audioElement *ngIf=\"audio && audio.length > 0\" id=\"audioElement\" [src]=\"audio\">\r\n {{translatedMessages.browserNotSupportAudio[language]}}\r\n </audio>\r\n <div class=\"captcha-buttons-container\">\r\n <button class=\"captcha-button play-audio-button\" href=\"javascript:void(0)\" (click)=\"playAudio()\" role=\"button\">\r\n <svg *ngIf=\"!fetchingAudioInProgress\" class=\"icon-play\"><use xlink:href=\"#icon-play-def\"></use></svg>\r\n\r\n <svg *ngIf=\"fetchingAudioInProgress\" class=\"audio-spinner\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"xMidYMid\"><g transform=\"rotate(0 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.8888888888888888s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(40 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.7777777777777778s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(80 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.6666666666666666s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(120 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.5555555555555556s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(160 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.4444444444444444s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(200 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.3333333333333333s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(240 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.2222222222222222s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(280 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"-0.1111111111111111s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g><g transform=\"rotate(320 50 50)\">\r\n <rect x=\"45\" y=\"9\" rx=\"2.7\" ry=\"0.54\" width=\"10\" height=\"22\" fill=\"#fff\">\r\n <animate attributeName=\"opacity\" values=\"1;0\" times=\"0;1\" dur=\"1s\" begin=\"0s\" repeatCount=\"indefinite\"></animate>\r\n </rect>\r\n </g></svg>\r\n\r\n <span>{{translatedMessages.playAudio[language]}}</span>\r\n </button>\r\n\r\n <button class=\"captcha-button try-another-image\" href=\"javascript:void(0)\" (click)=\"retryFetchCaptcha()\" role=\"button\">\r\n <svg class=\"icon-loop icon-loop-def\"><use xlink:href=\"#icon-loop-def\"></use></svg>\r\n <span>{{translatedMessages.tryAnotherImg[language]}}</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"captcha-input-container\">\r\n <label for=\"answer\">\r\n {{userPromptMessage || translatedMessages.userPromptMessage[language]}}\r\n <input id=\"answer\" type=\"text\"\r\n #userAnswerRef = \"ngModel\"\r\n [(ngModel)]=\"answer\"\r\n (input)=\"answerChanged($event)\"\r\n class=\"captcha-input\"\r\n (blur)='onBlur()'\r\n [ngClass]=\"{'captcha-wrong-answer': userAnswerRef.dirty && incorrectAnswer}\"\r\n name=\"answer\"\r\n maxlength=\"6\"\r\n required\r\n autocorrect=\"off\"\r\n autocomplete=\"off\"\r\n autocapitalize=\"none\"\r\n aria-required=\"true\">\r\n </label>\r\n </div>\r\n </div>\r\n <div>\r\n\r\n <div class=\"error-captcha\" *ngIf=\"state === 3\" role=\"alert\" aria-live=\"assertive\">\r\n <div>\r\n <svg class=\"icon-exclamation-triangle\"><use xlink:href=\"#icon-exclamation-triangle-def\"></use></svg>\r\n\r\n <span> {{translatedMessages.errorRetrievingImg[language].substring(0,translatedMessages.errorRetrievingImg[language].indexOf('{'))}}\r\n <button class=\"error-fetching-button captcha-button\" href=\"javascript:void(0)\" (click)=\"retryFetchCaptcha()\">{{translatedMessages.errorRetrievingImg[language].substring(translatedMessages.errorRetrievingImg[language].lastIndexOf('{')+1,translatedMessages.errorRetrievingImg[language].indexOf('}'))}}</button>\r\n {{translatedMessages.errorRetrievingImg[language].substring(translatedMessages.errorRetrievingImg[language].lastIndexOf('}')+1)}}\r\n </span>\r\n </div>\r\n\r\n <div>\r\n {{errorFetchingImg}}\r\n </div>\r\n </div>\r\n\r\n <div class=\"spinner-box\" *ngIf=\"state == 4\" role=\"alert\" aria-live=\"assertive\">\r\n <span>{{translatedMessages.verifyingAnswer[language]}}</span>\r\n </div>\r\n <div class=\"error-captcha\" *ngIf=\"state === 6\" role=\"alert\" aria-live=\"assertive\">\r\n <svg class=\"icon-exclamation-triangle\"><use xlink:href=\"#icon-exclamation-triangle-def\"></use></svg>\r\n <span>{{translatedMessages.errorVerifyingAnswer[language].substring(0,translatedMessages.errorVerifyingAnswer[language].indexOf('{'))}}\r\n <button class=\"error-verifying-button captcha-button\" href=\"javascript:void(0)\" (click)=\"retryFetchCaptcha()\">{{translatedMessages.errorVerifyingAnswer[language].substring(translatedMessages.errorVerifyingAnswer[language].lastIndexOf('{')+1,translatedMessages.errorVerifyingAnswer[language].indexOf('}'))}}</button>\r\n {{translatedMessages.errorVerifyingAnswer[language].substring(translatedMessages.errorVerifyingAnswer[language].lastIndexOf('}')+1)}}\r\n </span>\r\n <p>\r\n </p>\r\n </div>\r\n\r\n <div class=\"captcha-error\" *ngIf=\"incorrectAnswer === true\" role=\"alert\" aria-live=\"assertive\">\r\n {{translatedMessages.incorrectAnswer[language]}}\r\n </div>\r\n\r\n <div class=\"captcha-error\" *ngIf=\"state === 2 && !incorrectAnswer && controlDir?.touched && controlDir?.errors?.required\" role=\"alert\" aria-live=\"assertive\">\r\n Field is required.\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"confirm-correct-answer\" *ngIf=\"state === 5\" role=\"alert\" aria-live=\"assertive\">\r\n <svg class=\"icon-check\"><use xlink:href=\"#icon-check-def\"></use></svg>\r\n {{translatedMessages.correct[language]}} <span>{{successMessage || translatedMessages.successMessage[language]}}</span>\r\n </div>\r\n</div>\r\n", styles: [".bcgov-captcha{text-align:left}.bcgov-captcha .confirm-correct-answer{display:block;color:green}.bcgov-captcha .confirm-correct-answer i{color:green}.bcgov-captcha .spinner-box{height:60px;margin:2px 10px 6px;padding:5px 10px 5px 18px;display:flex;align-items:center}.bcgov-captcha .error-captcha{margin-left:10px}.bcgov-captcha .error-captcha svg{color:#ff8c00}.bcgov-captcha .error-captcha p{margin-left:32px}.bcgov-captcha .captcha-box-visible{display:block}.bcgov-captcha .captcha-box-invisible{display:none}.bcgov-captcha .captcha-image{display:inline-block;border:1px solid gray;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.bcgov-captcha .play-audio-button{margin-bottom:3px}.bcgov-captcha .has-error{border-color:#dc3545}.bcgov-captcha .has-error:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.bcgov-captcha input[type=text]{display:block;margin:0;width:100%;font-size:20px;box-shadow:none;border-radius:none;padding:6px;border:1px solid #ccc;transition:box-shadow .3s,border .3s}.bcgov-captcha input[type=text]:focus{border:1px solid #fff;box-shadow:0 0 1px 1px #2196f3;outline:0}.bcgov-captcha input[type=text].captcha-wrong-answer{border:1px solid #a94442}.bcgov-captcha .captcha-error{color:#a94442}.bcgov-captcha .icon-check,.bcgov-captcha .icon-exclamation-triangle,.bcgov-captcha .icon-loop,.bcgov-captcha .icon-play{display:inline-block;width:1rem;height:1rem;stroke-width:0;stroke:currentColor;fill:currentColor}.bcgov-captcha .spinner{-webkit-animation:1.4s linear infinite rotator;animation:1.4s linear infinite rotator}@-webkit-keyframes rotator{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}}@keyframes rotator{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}}.bcgov-captcha .path{stroke-dasharray:187;stroke-dashoffset:0;-webkit-transform-origin:center;transform-origin:center;-webkit-animation:1.4s ease-in-out infinite dash,5.6s ease-in-out infinite colors;animation:1.4s ease-in-out infinite dash,5.6s ease-in-out infinite colors}@-webkit-keyframes colors{0%{stroke:#9e9e9e}25%{stroke:#757575}50%{stroke:#616161}75%{stroke:#424242}100%{stroke:#212121}}@keyframes colors{0%{stroke:#9e9e9e}25%{stroke:#757575}50%{stroke:#616161}75%{stroke:#424242}100%{stroke:#212121}}@-webkit-keyframes dash{0%{stroke-dashoffset:187}50%{stroke-dashoffset:46.75;-webkit-transform:rotate(135deg);transform:rotate(135deg)}100%{stroke-dashoffset:187;-webkit-transform:rotate(450deg);transform:rotate(450deg)}}@keyframes dash{0%{stroke-dashoffset:187}50%{stroke-dashoffset:46.75;-webkit-transform:rotate(135deg);transform:rotate(135deg)}100%{stroke-dashoffset:187;-webkit-transform:rotate(450deg);transform:rotate(450deg)}}.bcgov-captcha .captcha-button{background-color:#036;border:none;border-radius:4px;color:#fff;padding:5px 10px;text-align:center;text-decoration:none;font-size:10px;font-family:BCSans,'Noto Sans',Verdana,Arial,sans-serif;font-weight:700;letter-spacing:1px;cursor:pointer;box-sizing:border-box;justify-content:center;align-items:center;display:flex}.bcgov-captcha .captcha-button.error-fetching-button,.bcgov-captcha .captcha-button.error-verifying-button{display:inline-block}.bcgov-captcha .captcha-button:hover{text-decoration:underline;opacity:.8}.bcgov-captcha .captcha-button:focus{outline:#3b99fc solid 4px;outline-offset:1px}.bcgov-captcha .captcha-button:active{opacity:1}.bcgov-captcha .captcha-input-container{max-width:420px}.bcgov-captcha .captcha-input-container>label{text-align:left}.bcgov-captcha .captcha-buttons-container{display:flex;flex-direction:column;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;justify-content:space-between;margin-bottom:4px}.bcgov-captcha .captcha-buttons-container>button{height:28px}.bcgov-captcha .captcha-buttons-container>button>span{margin-left:4px}.bcgov-captcha .captcha-form{display:flex;flex-direction:column}.bcgov-captcha .captcha-image-and-buttons-container{display:flex;flex-direction:column;flex-flow:wrap;justify-content:space-between;max-width:315px}.bcgov-captcha .defs{width:0;height:0;overflow:hidden}.bcgov-captcha .audio-spinner{display:inline-block;width:15px;height:15px;stroke-width:0;stroke:currentColor;fill:currentColor}.bcgov-captcha .captcha-spinner{display:inline-block;width:50px;height:50px;stroke-width:0;stroke:currentColor;fill:currentColor}"] }] } ]; /** @nocollapse */ CaptchaComponent.ctorParameters = () => [ { type: CaptchaDataService }, { type: ChangeDetectorRef }, { type: NgZone }, { type: NgControl, decorators: [{ type: Optional }, { type: Self }] } ]; CaptchaComponent.propDecorators = { imageContainer: [{ type: ViewChild, args: ['image',] }], audioElement: [{ type: ViewChild, args: ['audioElement',] }], apiBaseUrl: [{ type: Input, args: ['apiBaseUrl',] }], nonce: [{ type: Input, args: ['nonce',] }], onValidToken: [{ type: Output }], successMessage: [{ type: Input, args: ['successMessage',] }], eagerFetchAudio: [{ type: Input, args: ['eagerFetchAudio',] }], language: [{ type: Input, args: ['language',] }], userPromptMessage: [{ type: Input, args: ['userPromptMessage',] }] }; if (false) { /** @type {?} */ CaptchaComponent.prototype.imageContainer; /** @type {?} */ CaptchaComponent.prototype.audioElement; /** @type {?} */ CaptchaComponent.prototype.apiBaseUrl; /** @type {?} */ CaptchaComponent.prototype.nonce; /** @type {?} */ CaptchaComponent.prototype.onValidToken; /** @type {?} */ CaptchaComponent.prototype.successMessage; /** @type {?} */ CaptchaComponent.prototype.eagerFetchAudio; /** @type {?} */ CaptchaComponent.prototype.language; /** @type {?} */ CaptchaComponent.prototype.userPromptMessage; /** * Http error response for fetching a CAPTCHA image. * @type {?} */ CaptchaComponent.prototype.errorFetchingImg; /** * Http error response for verifying user's answer. * @type {?} */ CaptchaComponent.prototype.errorVerifyAnswer; /** * @type {?} * @private */ CaptchaComponent.prototype.validation; /** @type {?} */ CaptchaComponent.prototype.audio; /** @type {?} */ CaptchaComponent.prototype.answer; /** @type {?} */ CaptchaComponent.prototype.state; /** @type {?} */ CaptchaComponent.prototype.incorrectAnswer; /** @type {?} */ CaptchaComponent.prototype.fetchingAudioInProgress; /** @type {?} */ CaptchaComponent.prototype._onChange; /** @type {?} */ CaptchaComponent.prototype._onTouched; /** @type {?} */ CaptchaComponent.prototype.translatedMessages; /** * @type {?} * @private */ CaptchaComponent.prototype.dataService; /** * @type {?} * @private */ CaptchaComponent.prototype.cd; /** * @type {?} * @private */ CaptchaComponent.prototype.ngZone; /** @type {?} */ CaptchaComponent.prototype.controlDir; } /** @enum {number} */ const CAPTCHA_STATE = { FETCHING_CAPTCHA_IMG: 1, SUCCESS_FETCH_IMG: 2, ERROR_FETCH_IMG: 3, VERIFYING_ANSWER: 4, SUCCESS_VERIFY_ANSWER_CORRECT: 5, // http error during verification call. ERROR_VERIFY: 6, }; CAPTCHA_STATE[CAPTCHA_STATE.FETCHING_CAPTCHA_IMG] = 'FETCHING_CAPTCHA_IMG'; CAPTCHA_STATE[CAPTCHA_STATE.SUCCESS_FETCH_IMG] = 'SUCCESS_FETCH_IMG'; CAPTCHA_STATE[CAPTCHA_STATE.ERROR_FETCH_IMG] = 'ERROR_FETCH_IMG'; CAPTCHA_STATE[CAPTCHA_STATE.VERIFYING_ANSWER] = 'VERIFYING_ANSWER'; CAPTCHA_STATE[CAPTCHA_STATE.SUCCESS_VERIFY_ANSWER_CORRECT] = 'SUCCESS_VERIFY_ANSWER_CORRECT'; CAPTCHA_STATE[CAPTCHA_STATE.ERROR_VERIFY] = 'ERROR_VERIFY'; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwdGNoYS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9tb2gtY29tbW9uLWxpYi9jYXB0Y2hhLyIsInNvdXJjZXMiOlsiY2FwdGNoYS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBaUIsTUFBTSxFQUN2RCxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFvQyxZQUFZLEVBQUUsUUFBUSxFQUFFLElBQUksRUFDakcsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFNBQVMsRUFBd0IsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QmpFLE1BQU0sT0FBTyxnQkFBZ0I7Ozs7Ozs7SUFvQzNCLFlBQW9CLFdBQStCLEVBQ3pDLEVBQXFCLEVBQ3JCLE1BQWMsRUFDSyxVQUFxQjtRQUg5QixnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFDekMsT0FBRSxHQUFGLEVBQUUsQ0FBbUI7UUFDckIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNLLGVBQVUsR0FBVixVQUFVLENBQVc7O1FBL0J4QyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFHakMsYUFBUSxHQUFXLElBQUksQ0FBQzs7OztRQU0zQyxxQkFBZ0IsR0FBRyxJQUFJLENBQUM7Ozs7UUFLeEIsc0JBQWlCLEdBQUcsSUFBSSxDQUFDO1FBRWpCLGVBQVUsR0FBRyxFQUFFLENBQUM7UUFDakIsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUNYLFdBQU0sR0FBRyxFQUFFLENBQUM7UUFLWiw0QkFBdUIsR0FBRyxLQUFLLENBQUM7UUFFaEMsY0FBUzs7OztRQUFHLENBQUMsQ0FBTSxFQUFFLEVBQUUsR0FBRSxDQUFDLEVBQUM7UUFDM0IsZUFBVTs7O1FBQUcsR0FBRyxFQUFFLEdBQUUsQ0FB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QkErRGIsUUFBUSxZQUFJLElBQUk7Ozs2QkFyQ2xCLFNBQVMsU0FBQyxPQUFPOzJCQUNqQixTQUFTLFNBQUMsY0FBYzt5QkFFeEIsS0FBSyxTQUFDLFlBQVk7b0JBQ2xCLEtBQUssU0FBQyxPQUFPOzJCQUViLE1BQU07NkJBQ04sS0FBSyxTQUFDLGdCQUFnQjs4QkFDdEIsS0FBSyxTQUFDLGlCQUFpQjt1QkFDdkIsS0FBSyxTQUFDLFVBQVU7Z0NBQ2hCLEtBQUssU0FBQyxtQkFBbUI7Ozs7SUFWMUIsMENBQStDOztJQUMvQyx3Q0FBb0Q7O0lBRXBELHNDQUF3Qzs7SUFDeEMsaUNBQThCOztJQUU5Qix3Q0FBb0Q7O0lBQ3BELDBDQUFnRDs7SUFDaEQsMkNBQWtEOztJQUNsRCxvQ0FBMkM7O0lBQzNDLDZDQUFzRDs7Ozs7SUFLdEQsNENBQXdCOzs7OztJQUt4Qiw2Q0FBeUI7Ozs7O0lBRXpCLHNDQUF3Qjs7SUFDeEIsaUNBQWtCOztJQUNsQixrQ0FBbUI7O0lBRW5CLGlDQUFxQjs7SUFDckIsMkNBQXlCOztJQUV6QixtREFBdUM7O0lBRXZDLHFDQUFrQzs7SUFDbEMsc0NBQTZCOztJQTZNN0IsOENBbUVFOzs7OztJQTlRVSx1Q0FBdUM7Ozs7O0lBQ2pELDhCQUE2Qjs7Ozs7SUFDN0Isa0NBQXNCOztJQUN0QixzQ0FBZ0Q7Ozs7SUFtUmxELHVCQUF3QjtJQUN4QixvQkFBcUI7SUFDckIsa0JBQW1CO0lBQ25CLG1CQUFvQjtJQUNwQixnQ0FBaUM7SUFDakMsdUNBQXVDO0lBQ3ZDLGVBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCwgU2ltcGxlQ2hhbmdlcywgTmdab25lLFxyXG4gIENoYW5nZURldGVjdG9yUmVmLCBPdXRwdXQsIElucHV0LCBBZnRlclZpZXdJbml0LCBPbkluaXQsIE9uQ2hhbmdlcywgRXZlbnRFbWl0dGVyLCBPcHRpb25hbCwgU2VsZlxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBIdHRwUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IENhcHRjaGFEYXRhU2VydmljZSB9IGZyb20gJy4vY2FwdGNoYS1kYXRhLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOZ0NvbnRyb2wsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBDQVBUQ0hBIGNhbiBkaXNwbGF5IGEgXCJyZXF1aXJlZFwiIGVycm9yIGF1dG9tYXRpY2FsbHkgd2hlbiB5b3UgcHJvZ3JhbW1haWNhbGx5XHJcbiAqIGNhbGwgYG1hcmtBbGxJbnB1c0FzVG91Y2hlZCgpYC4gKEBzZWUgQWJzdHJhY3RGb3JtKS4gIEluIG9yZGVyIHRvIGRvIHRoaXMsXHJcbiAqIHlvdSBtdXN0IHNldDogbmFtZSwgbmdNb2RlbCwgYW5kIHJlcXVpcmVkLiAgT3RoZXJ3aXNlLCB0aGVzZSBmaWVsZHMgYXJlXHJcbiAqIG9wdGlvbmFsLlxyXG4gKlxyXG4gKiAgQGV4YW1wbGVcclxuICogICAgICAgICAgIDxjb21tb24tY2FwdGNoYVxyXG4gKiAgICAgICAgICAgICAgIFtub25jZV09XCJhcHBsaWNhdGlvbi51dWlkXCJcclxuICogICAgICAgICAgICAgICBbYXBpQmFzZVVybF09XCJjYXB0Y2hhQXBpQmFzZVVybFwiXHJcbiAqICAgICAgICAgICAgICAgKG9uVmFsaWRUb2tlbik9XCJzZXRUb2tlbigkZXZlbnQpXCJcclxuICogICAgICAgICAgICAgICBuYW1lPSdjYXB0Y2hhJ1xyXG4gKiAgICAgICAgICAgICAgIG5nTW9kZWxcclxuICogICAgICAgICAgICAgICByZXF1aXJlZD5cclxuICogICAgICAgICAgIDwvY29tbW9uLWNhcHRjaGE+XHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2NvbW1vbi1jYXB0Y2hhJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vY2FwdGNoYS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vY2FwdGNoYS5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDYXB0Y2hhQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcclxuXHJcbiAgQFZpZXdDaGlsZCgnaW1hZ2UnKSBpbWFnZUNvbnRhaW5lcjogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdhdWRpb0VsZW1lbnQnKSBhdWRpb0VsZW1lbnQ6IEVsZW1lbnRSZWY7XHJcbiAgLy8gdHNsaW50OmRpc2FibGU6bm8taW5wdXQtcmVuYW1lXHJcbiAgQElucHV0KCdhcGlCYXNlVXJsJykgYXBpQmFzZVVybDogc3RyaW5nO1xyXG4gIEBJbnB1dCgnbm9uY2UnKSBub25jZTogc3RyaW5nO1xyXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1vdXRwdXQtb24tcHJlZml4XHJcbiAgQE91dHB1dCgpIG9uVmFsaWRUb2tlbiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG4gIEBJbnB1dCgnc3VjY2Vzc01lc3NhZ2UnKSBzdWNjZXNzTWVzc2FnZTogc3RyaW5nO1xyXG4gIEBJbnB1dCgnZWFnZXJGZXRjaEF1ZGlvJykgZWFnZXJGZXRjaEF1ZGlvOiBzdHJpbmc7XHJcbiAgQElucHV0KCdsYW5ndWFnZScpIGxhbmd1YWdlOiBzdHJpbmcgPSAnZW4nO1xyXG4gIEBJbnB1dCgndXNlclByb21wdE1lc3NhZ2UnKSB1c2VyUHJvbXB0TWVzc2FnZTogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBIdHRwIGVycm9yIHJlc3BvbnNlIGZvciBmZXRjaGluZyBhIENBUFRDSEEgaW1hZ2UuXHJcbiAgICovXHJcbiAgZXJyb3JGZXRjaGluZ0ltZyA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIEh0dHAgZXJyb3IgcmVzcG9uc2UgZm9yIHZlcmlmeWluZyB1c2VyJ3MgYW5zd2VyLlxyXG4gICAqL1xyXG4gIGVycm9yVmVyaWZ5QW5zd2VyID0gbnVsbDtcclxuXHJcbiAgcHJpdmF0ZSB2YWxpZGF0aW9uID0gJyc7XHJcbiAgcHVibGljIGF1ZGlvID0gJyc7XHJcbiAgcHVibGljIGFuc3dlciA9ICcnO1xyXG5cclxuICBzdGF0ZTogQ0FQVENIQV9TVEFURTtcclxuICBpbmNvcnJlY3RBbnN3ZXI6IGJvb2xlYW47XHJcblxyXG4gIHB1YmxpYyBmZXRjaGluZ0F1ZGlvSW5Qcm9ncmVzcyA9IGZhbHNlO1xyXG5cclxuICBwdWJsaWMgX29uQ2hhbmdlID0gKF86IGFueSkgPT4ge307XHJcbiAgcHVibGljIF9vblRvdWNoZWQgPSAoKSA9PiB7fTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhU2VydmljZTogQ2FwdGNoYURhdGFTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxyXG4gICAgQE9wdGlvbmFsKCkgQFNlbGYoKSBwdWJsaWMgY29udHJvbERpcjogTmdDb250cm9sICApIHtcclxuICAgICAgaWYgKCBjb250cm9sRGlyICkge1xyXG4gICAgICAgIGNvbnRyb2xEaXIudmFsdWVBY2Nlc3NvciA9IHRoaXM7XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5fb25DaGFuZ2UgPSBmbjtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuX29uVG91Y2hlZCA9IGZ