moh-common-lib
Version:
A library of Angular components, services, and styles for B.C. Government Ministry of Health (MoH).
702 lines • 66.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter, forwardRef, ViewChild } from '@angular/core';
import { ControlContainer, NgForm, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Base } from '../../models/base';
import { Address } from '../../models/address.model';
import { CANADA, COUNTRY_LIST } from '../country/country.component';
import { BRITISH_COLUMBIA, PROVINCE_LIST } from '../province/province.component';
import { CityComponent } from '../city/city.component';
/**
* @record
*/
export function AddrLabelList() { }
if (false) {
/** @type {?|undefined} */
AddrLabelList.prototype.address1;
/** @type {?|undefined} */
AddrLabelList.prototype.address2;
/** @type {?|undefined} */
AddrLabelList.prototype.address3;
/** @type {?|undefined} */
AddrLabelList.prototype.city;
/** @type {?|undefined} */
AddrLabelList.prototype.province;
/** @type {?|undefined} */
AddrLabelList.prototype.country;
/** @type {?|undefined} */
AddrLabelList.prototype.postalCode;
}
/**
* @record
*/
export function Maxlengths() { }
if (false) {
/** @type {?|undefined} */
Maxlengths.prototype.address;
/** @type {?|undefined} */
Maxlengths.prototype.city;
/** @type {?|undefined} */
Maxlengths.prototype.province;
/** @type {?|undefined} */
Maxlengths.prototype.country;
/** @type {?|undefined} */
Maxlengths.prototype.postalCode;
}
/**
* @record
*/
export function ReadOnlyFields() { }
if (false) {
/** @type {?|undefined} */
ReadOnlyFields.prototype.address;
/** @type {?|undefined} */
ReadOnlyFields.prototype.city;
/** @type {?|undefined} */
ReadOnlyFields.prototype.province;
/** @type {?|undefined} */
ReadOnlyFields.prototype.country;
/** @type {?|undefined} */
ReadOnlyFields.prototype.postalCode;
}
/**
*
* Note - This component REQUIRES that `HttpClientModule` is registered in your NgModule.
*/
export class AddressComponent extends Base {
constructor() {
super();
/* Disable all fields by sending in boolean,
* disable specific fields by sending in ReadOnlyFields structure
*/
this.disabled = false;
this.isRequired = false;
this.countryList = COUNTRY_LIST;
this.defaultCountry = CANADA;
this.provinceList = PROVINCE_LIST;
this.defaultProvince = BRITISH_COLUMBIA;
this.disableGeocoder = false; // This should eventually be refactored to `disableAddressValidator`. Leaving it for compatibility.
this.bcOnly = false;
this.addressChange = new EventEmitter();
/**
* If true, adds a plus icon next to street and enables users to add a second
* address line. This value binds to `address.addressLine2`
*/
this.allowExtralines = false;
this.showLine2 = false;
this.showLine3 = false;
// Labels defaulted to MSP
this.addrLabels = {
address1: 'Full street address, rural route, PO box or general delivery',
address2: 'Address Line 2',
address3: 'Address Line 3',
city: 'City',
province: 'Province or state',
country: 'Jurisdiction',
postalCode: 'Postal Code or Zip Code'
};
// Lengths defaulted to MSP
this.fieldMaxLengths = {
address: '25',
city: '25',
province: '25',
country: '250',
postalCode: '25'
};
this.readOnlyFields = {
address: false,
city: false,
province: false,
country: false,
postalCode: false,
};
this._onChange = (/**
* @param {?} _
* @return {?}
*/
(_) => { });
this._onTouched = (/**
* @param {?} _
* @return {?}
*/
(_) => { });
}
/**
* @param {?} val
* @return {?}
*/
set address(val) {
if (val) {
this.addr = val;
}
}
/**
* @return {?}
*/
get address() {
return this.addr;
}
/**
* @return {?}
*/
ngOnInit() {
this.setLabels();
this.setMaxlengths();
this.setReadOnlyFields();
if (this.addr) {
if (!this.addr.country) {
this.addr.country = this.setDefaultCountryAsOption();
}
else {
// If string for country submitted, need to find code to display value in select box
this.addr.country = this.findCountryCode(this.addr.country);
}
if (!this.addr.province) {
this.addr.province = this.setDefaultProvinceAsOption(this.addr.country);
}
// Make sure addressLine2 is visible if there is data persisted to display there.
if (this.allowExtralines) {
if (this.addr.addressLine2) {
this.addLine(2);
}
if (this.addr.addressLine3) {
this.addLine(3);
}
}
}
this.updateProvList();
}
/**
* Set country province blank
* @param {?} value
* @return {?}
*/
setCountry(value) {
this.addr.province = this.setDefaultProvinceAsOption(value);
this.addr.country = value;
this.updateProvList();
if (this.isCanada()) {
// If Canada, clear postal code to display mask
this.addr.postal = '';
if (!this.disableGeocoder) {
this.showLine2 = false;
this.showLine3 = false;
this.addr.addressLine2 = '';
this.addr.addressLine3 = '';
}
}
this._onChange(this.addr);
this.addressChange.emit(this.addr);
this._onTouched(this.addr);
}
/**
* @param {?} value
* @return {?}
*/
setProvince(value) {
this.addr.province = value;
this._onChange(this.addr);
this.addressChange.emit(this.addr);
this._onTouched(this.addr);
}
/**
* @param {?} value
* @return {?}
*/
setStreetAddress(value) {
// When emptying a search result from address validator, clear the rest of the fields as well.
if (value === '' && !this.disableGeocoder) {
this.addr.addressLine1 = '';
this.addr.addressLine2 = '';
this.addr.addressLine3 = '';
this.addr.city = '';
this.addr.postal = '';
if (!this.bcOnly) {
this.addr.province = BRITISH_COLUMBIA;
this.addr.country = CANADA;
}
if (this.allowExtralines) {
this.showLine2 = false;
this.showLine3 = false;
}
}
this.addr.addressLine1 = value;
this._onChange(this.addr);
this.addressChange.emit(this.addr);
this._onTouched(this.addr);
}
/**
* @param {?} value
* @return {?}
*/
setCity(value) {
this.addr.city = value;
this._onChange(this.addr);
this.addressChange.emit(this.addr);
this._onTouched(this.addr);
}
/**
* Sets string after converted upper case
* @param {?} value
* @return {?}
*/
setPostalCode(value) {
this.addr.postal = value;
this._onChange(this.addr);
this.addressChange.emit(this.addr);
this._onTouched(this.addr);
}
/**
* @return {?}
*/
isCanada() {
return this.addr && CANADA === this.addr.country;
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (changes['countryList'] && changes['countryList'].currentValue) {
if (this.addr && !this.addr.country) {
// Set defaults
this.addr.country = this.setDefaultCountryAsOption();
// Set defaults
this.addr.province = this.setDefaultProvinceAsOption(this.addr.country);
}
this.updateProvList();
}
if (changes['provinceList'] && changes['provinceList'].currentValue) {
if (this.addr && !this.addr.province) {
// Set defaults
this.addr.province = this.setDefaultProvinceAsOption(this.addr.country);
}
this.updateProvList();
}
}
/**
* @param {?=} line
* @return {?}
*/
addLine(line = null) {
// Add lines in order
if (line === null) {
if (!this.showLine2) {
this.showLine2 = true;
}
else if (!this.showLine3) {
this.showLine3 = true;
}
}
else {
// Add specific line number
/** @type {?} */
const lookup = `showLine${line}`;
this[lookup] = true;
}
}
/**
* @param {?} line
* @return {?}
*/
removeLine(line) {
// We can remove lines in any order, depending on user input
// Dynamically lookup variable based on line number input.
/** @type {?} */
const lookup = `showLine${line}`;
this[lookup] = false;
// TODO - Need to clear the data in the appropriate field, just null/undefined it out.
/** @type {?} */
const addrLookup = `addressLine${line}`;
this.address[addrLookup] = undefined;
}
/**
* Updates the provList variable. Values must be stored in a variable and not
* accessed via function invocation for performance.
* @private
* @return {?}
*/
updateProvList() {
if (!this.provinceList) {
return;
} // When data is async and hasn't loaded
this.provList = this.provinceList
.map((/**
* @param {?} prov
* @return {?}
*/
prov => {
if (prov.country === this.addr.country) {
return prov;
}
}))
.filter((/**
* @param {?} x
* @return {?}
*/
x => x));
}
/**
* Sets the default province option value
* @private
* @param {?} country
* @return {?}
*/
setDefaultProvinceAsOption(country) {
/** @type {?} */
const provObj = !this.provinceList ? null : this.provinceList.find((/**
* @param {?} val
* @return {?}
*/
val => (val.provinceCode === this.defaultProvince ||
val.description === this.defaultProvince) &&
val.country === country));
return (provObj ? provObj.provinceCode : '');
}
/**
* @private
* @param {?} prov
* @return {?}
*/
findProvinceDescription(prov) {
/** @type {?} */
const provObj = !this.provinceList ? null : this.provinceList.find((/**
* @param {?} val
* @return {?}
*/
val => val.provinceCode === prov ||
val.description === prov));
return (provObj ? provObj.description : null);
}
/**
* Set country to default
* Search uses country code or country name to find item is list.
* @private
* @return {?}
*/
setDefaultCountryAsOption() {
return this.findCountryCode(this.defaultCountry);
}
/**
* @private
* @param {?} country
* @return {?}
*/
findCountryCode(country) {
/** @type {?} */
const countryObj = !this.countryList
? null
: this.countryList.find((/**
* @param {?} val
* @return {?}
*/
val => val.countryCode === country ||
val.description === country));
return countryObj ? countryObj.countryCode : null;
}
/**
* @return {?}
*/
get useAddressValidator() {
if (this.disableGeocoder) {
return false;
}
return this.isCanada();
}
// Only BC addresses therefore no need to copy province into structure.
/**
* @param {?} data
* @return {?}
*/
setAddress(data) {
this.addr.addressLine1 = data.street;
this.addr.city = data.city;
this.addr.province = data.province;
this.addr.country = data.country;
this.addressChange.emit(this.addr);
}
/**
* @param {?} address
* @return {?}
*/
selectSuggestedAddress(address) {
if (!address.street && !address.city && !address.postal) {
return;
}
// Truncate long addresses and drop them down a line to addressLine2 etc.
address = this.truncateAddressLines(address);
if (this.bcOnly && address.province != BRITISH_COLUMBIA) {
alert('Please select a valid BC address.');
setTimeout((/**
* @return {?}
*/
() => {
this.addr.addressLine1 = '';
this.addr.addressLine2 = '';
this.addr.addressLine3 = '';
}), 0);
return;
}
// Placed in timeout to override ngx-bootstrap population.
setTimeout((/**
* @return {?}
*/
() => {
this.addr.addressLine1 = address.addressLine1 || '';
}), 0);
if (this.allowExtralines) {
this.addr.addressLine2 = address.addressLine2 || '';
this.addr.addressLine3 = address.addressLine3 || '';
if (address.addressLine2) {
this.showLine2 = true;
}
if (address.addressLine3) {
this.showLine3 = true;
}
}
this.addr.city = address.city;
if (this._cityComponent) {
this._cityComponent.onValueChange(this.addr.city);
}
this.addr.postal = address.postal;
if (!this.bcOnly) {
this.addr.province = address.province;
}
this._onChange(this.addr);
this.addressChange.emit(this.addr);
this._onTouched(this.addr);
}
/**
* @param {?} value
* @return {?}
*/
writeValue(value) {
if (value) {
this.addr = value;
}
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this._onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this._onTouched = fn;
}
/**
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
this.setReadOnlyFields();
}
/**
* @private
* @return {?}
*/
setLabels() {
if (this.labels) {
Object.keys(this.labels).map((/**
* @param {?} x
* @return {?}
*/
x => this.addrLabels[x] = this.labels[x]));
}
}
/**
* @private
* @return {?}
*/
setMaxlengths() {
if (this.maxlengths) {
Object.keys(this.fieldMaxLengths).map((/**
* @param {?} x
* @return {?}
*/
x => this.maxlengths[x] = this.fieldMaxLengths[x]));
}
}
/**
* @private
* @return {?}
*/
setReadOnlyFields() {
if (typeof this.disabled === 'boolean') {
Object.keys(this.readOnlyFields).map((/**
* @param {?} x
* @return {?}
*/
x => this.readOnlyFields[x] = this.disabled));
}
else {
Object.keys(this.disabled).map((/**
* @param {?} x
* @return {?}
*/
x => this.readOnlyFields[x] = this.disabled[x]));
}
}
/**
* @private
* @param {?} address
* @return {?}
*/
truncateAddressLines(address) {
/** @type {?} */
const maxlength = parseInt(this.fieldMaxLengths.address, 10);
/** @type {?} */
const lines = [];
/** @type {?} */
const newLines = [];
/** @type {?} */
let lineIndex = 0;
// console.log('Before truncation: ', address);
// Create `lines` array of address lines.
for (let i = 1; i <= 3; i++) {
if (address['addressLine' + i]) {
lines.push(address['addressLine' + i]);
}
}
for (let i = 0; i < lines.length; i++) {
if (!lines[i]) {
break;
}
newLines.push('');
/** @type {?} */
const words = lines[i].split(' ');
if (lines[i].length > maxlength && words.length > 1) {
// Iterate over words.
while (words.length > 0) {
newLines[lineIndex] += words[0] + ' ';
words.splice(0, 1);
if (words.length > 0) {
/** @type {?} */
const tempNextLine = newLines[lineIndex] + words[0];
// Add next line in case words remain.
if (tempNextLine.length > maxlength) {
newLines[lineIndex] = newLines[lineIndex].trim();
newLines.push('');
lineIndex++;
}
}
}
newLines[lineIndex] = newLines[lineIndex].trim();
}
else {
newLines[lineIndex] = lines[i];
}
lineIndex++;
}
;
for (let i = 0; i < newLines.length; i++) {
address['addressLine' + (i + 1)] = newLines[i];
}
// console.log('After truncatation: ', address);
return address;
}
}
AddressComponent.decorators = [
{ type: Component, args: [{
selector: 'common-address',
template: "<div class=\"form-group\">\r\n <div class=\"row\">\r\n <div [ngClass]=\"{'col-11': allowExtralines, 'col-12': !allowExtralines}\">\r\n <common-street *ngIf=\"!useAddressValidator\"\r\n name=\"street_{{objectId}}\"\r\n label=\"{{addrLabels.address1}}\"\r\n [ngModel]=\"addr?.addressLine1\"\r\n (ngModelChange)=\"setStreetAddress($event)\"\r\n (selectEvent)=\"setAddress($event)\"\r\n [required]=\"isRequired\"\r\n [disabled]=\"readOnlyFields.address\"\r\n [maxlength]=\"fieldMaxLengths.address\"\r\n commonValidateStreet></common-street>\r\n <!-- Address Validator -->\r\n <common-address-validator *ngIf=\"useAddressValidator\"\r\n name=\"street_{{objectId}}\"\r\n label=\"{{addrLabels.address1}}\"\r\n [(ngModel)]=\"addr.addressLine1\"\r\n (ngModelChange)=\"setStreetAddress($event)\"\r\n [required]=\"isRequired\"\r\n [disabled]=\"readOnlyFields.address\"\r\n [maxlength]=\"fieldMaxLengths.address\"\r\n [serviceUrl]=\"addressServiceUrl\"\r\n (select)=\"selectSuggestedAddress($event)\"\r\n [populateAddressOnSelect]=\"true\"\r\n commonValidateStreet>\r\n </common-address-validator>\r\n </div>\r\n\r\n <div class=\"col-1\"\r\n *ngIf='allowExtralines'>\r\n <div class=\"h-50\"></div>\r\n <button class=\" btn btn-transparent\"\r\n *ngIf='!(showLine2 && showLine3)'\r\n aria-label=\"Add Additional Address Line (optional)\"\r\n (click)=\"addLine()\">\r\n <i class=\"fa fa-plus\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n<div class=\"form-group\"\r\n *ngIf='showLine2'>\r\n <div class=\"row\">\r\n\r\n <div class=\"col-11\">\r\n <common-street label=\"{{addrLabels.address2}}\"\r\n name=\"street_line_2_{{objectId}}\"\r\n [(ngModel)]='addr.addressLine2'\r\n [maxlength]=\"fieldMaxLengths.address\"\r\n [disabled]=\"readOnlyFields.address\"\r\n commonValidateStreet></common-street>\r\n </div>\r\n <div class=\"col-1\">\r\n <div class=\"h-50\"></div>\r\n <button class=\"btn btn-transparent\"\r\n *ngIf=\"!showLine3\"\r\n aria-label='Remove Address Line 2'\r\n (click)=\"removeLine(2)\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"form-group\"\r\n *ngIf='showLine3'>\r\n <div class=\"row\">\r\n\r\n\r\n <div class=\"col-11\">\r\n <common-street label=\"{{addrLabels.address3}}\"\r\n name=\"street_line_3_{{objectId}}\"\r\n [(ngModel)]='addr.addressLine3'\r\n [maxlength]=\"fieldMaxLengths.address\"\r\n [disabled]=\"readOnlyFields.address\"\r\n commonValidateStreet></common-street>\r\n </div>\r\n <div class=\"col-1\">\r\n <div class=\"h-50\"></div>\r\n <button class=\" btn btn-transparent\"\r\n aria-label='Remove Address Line 3 '\r\n (click)=\"removeLine(3)\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n<div class=\"form-group col-sm-11 p-sm-0\">\r\n <common-city #city\r\n name=\"city_{{objectId}}\"\r\n label=\"{{addrLabels.city}}\"\r\n [ngModel]=\"addr?.city\"\r\n (ngModelChange)=\"setCity($event)\"\r\n [required]=\"isRequired\"\r\n [disabled]=\"readOnlyFields.city\"\r\n [maxlength]=\"fieldMaxLengths.city\"\r\n commonValidateCity></common-city>\r\n</div>\r\n\r\n<div class=\"form-group col-sm-11 p-sm-0\">\r\n <common-province name=\"province_{{objectId}}\"\r\n label=\"{{addrLabels.province}}\"\r\n [ngModel]=\"addr?.province\"\r\n (ngModelChange)=\"setProvince($event)\"\r\n [provinceList]=\"provList\"\r\n [required]=\"isRequired\"\r\n [disabled]=\"readOnlyFields.province\"\r\n placeholder=\"{{ isCanada()? 'Select a Province': 'Select a State' }}\"\r\n [useDropDownList]=\"isCanada()\"\r\n [maxlength]=\"fieldMaxLengths.province\"\r\n commonValidateRegion></common-province>\r\n</div>\r\n\r\n<div class=\"form-group col-sm-11 p-sm-0\">\r\n <common-country name=\"country_{{objectId}}\"\r\n label=\"{{addrLabels.country}}\"\r\n [countryList]=\"countryList\"\r\n [ngModel]=\"addr?.country\"\r\n (ngModelChange)=\"setCountry($event)\"\r\n [required]=\"isRequired\"\r\n [disabled]=\"readOnlyFields.country\"\r\n [maxlen]=\"fieldMaxLengths.country\"></common-country>\r\n</div>\r\n\r\n<div class=\"form-group col-sm-4 p-sm-0\">\r\n <common-postal-code name=\"pc_{{objectId}}\"\r\n label=\"{{addrLabels.postalCode}}\"\r\n [displayMask]=\"isCanada()\"\r\n [disabled]=\"readOnlyFields.postalCode\"\r\n [ngModel]=\"addr?.postal\"\r\n (ngModelChange)=\"setPostalCode($event)\"\r\n [required]=\"isRequired\"\r\n [maxlen]=\"fieldMaxLengths.postalCode\"\r\n commonValidatePostalcode\r\n [hasMask]=\"isCanada()\"\r\n [bcOnly]=\"bcOnly\"></common-postal-code>\r\n</div>\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 {?}
*/
() => NgForm)) }
],
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/**
* @return {?}
*/
() => AddressComponent)) }
]
}] }
];
/** @nocollapse */
AddressComponent.ctorParameters = () => [];
AddressComponent.propDecorators = {
disabled: [{ type: Input }],
isRequired: [{ type: Input }],
countryList: [{ type: Input }],
defaultCountry: [{ type: Input }],
provinceList: [{ type: Input }],
defaultProvince: [{ type: Input }],
disableGeocoder: [{ type: Input }],
labels: [{ type: Input }],
maxlengths: [{ type: Input }],
bcOnly: [{ type: Input }],
addressServiceUrl: [{ type: Input }],
_cityComponent: [{ type: ViewChild, args: ['city',] }],
address: [{ type: Input }],
addressChange: [{ type: Output }],
allowExtralines: [{ type: Input }]
};
if (false) {
/** @type {?} */
AddressComponent.prototype.disabled;
/** @type {?} */
AddressComponent.prototype.isRequired;
/** @type {?} */
AddressComponent.prototype.countryList;
/** @type {?} */
AddressComponent.prototype.defaultCountry;
/** @type {?} */
AddressComponent.prototype.provinceList;
/** @type {?} */
AddressComponent.prototype.defaultProvince;
/** @type {?} */
AddressComponent.prototype.disableGeocoder;
/** @type {?} */
AddressComponent.prototype.labels;
/** @type {?} */
AddressComponent.prototype.maxlengths;
/** @type {?} */
AddressComponent.prototype.bcOnly;
/** @type {?} */
AddressComponent.prototype.addressServiceUrl;
/**
* @type {?}
* @private
*/
AddressComponent.prototype._cityComponent;
/** @type {?} */
AddressComponent.prototype.addressChange;
/**
* If true, adds a plus icon next to street and enables users to add a second
* address line. This value binds to `address.addressLine2`
* @type {?}
*/
AddressComponent.prototype.allowExtralines;
/** @type {?} */
AddressComponent.prototype.addr;
/** @type {?} */
AddressComponent.prototype.provList;
/** @type {?} */
AddressComponent.prototype.showLine2;
/** @type {?} */
AddressComponent.prototype.showLine3;
/** @type {?} */
AddressComponent.prototype.addrLabels;
/** @type {?} */
AddressComponent.prototype.fieldMaxLengths;
/** @type {?} */
AddressComponent.prototype.readOnlyFields;
/** @type {?} */
AddressComponent.prototype._onChange;
/** @type {?} */
AddressComponent.prototype._onTouched;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkcmVzcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9tb2gtY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL2FkZHJlc3MvYWRkcmVzcy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBRVosVUFBVSxFQUVWLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQXdCLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25HLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUV6QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDckQsT0FBTyxFQUFlLE1BQU0sRUFBRSxZQUFZLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNqRixPQUFPLEVBQWdCLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQy9GLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7OztBQUV2RCxtQ0FRQzs7O0lBUEMsaUNBQWtCOztJQUNsQixpQ0FBa0I7O0lBQ2xCLGlDQUFrQjs7SUFDbEIsNkJBQWM7O0lBQ2QsaUNBQWtCOztJQUNsQixnQ0FBaUI7O0lBQ2pCLG1DQUFvQjs7Ozs7QUFHdEIsZ0NBTUM7OztJQUxDLDZCQUFpQjs7SUFDakIsMEJBQWM7O0lBQ2QsOEJBQWtCOztJQUNsQiw2QkFBaUI7O0lBQ2pCLGdDQUFvQjs7Ozs7QUFHdEIsb0NBTUM7OztJQUxDLGlDQUFrQjs7SUFDbEIsOEJBQWU7O0lBQ2Ysa0NBQW1COztJQUNuQixpQ0FBa0I7O0lBQ2xCLG9DQUFxQjs7Ozs7O0FBb0J2QixNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsSUFBSTtJQXdFeEM7UUFDRSxLQUFLLEVBQUUs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OzBCQUNMLEtBQUs7NkJBQ0wsS0FBSzsyQkFDTCxLQUFLOzhCQUNMLEtBQUs7OEJBQ0wsS0FBSztxQkFDTCxLQUFLO3lCQUNMLEtBQUs7cUJBQ0wsS0FBSztnQ0FDTCxLQUFLOzZCQUNMLFNBQVMsU0FBQyxNQUFNO3NCQUVoQixLQUFLOzRCQVVMLE1BQU07OEJBS04sS0FBSzs7OztJQTVCTixvQ0FBb0Q7O0lBQ3BELHNDQUFxQzs7SUFDckMsdUNBQW1EOztJQUNuRCwwQ0FBeUM7O0lBQ3pDLHdDQUFzRDs7SUFDdEQsMkNBQW9EOztJQUNwRCwyQ0FBMEM7O0lBQzFDLGtDQUErQjs7SUFDL0Isc0NBQWdDOztJQUNoQyxrQ0FBaUM7O0lBQ2pDLDZDQUFtQzs7Ozs7SUFDbkMsMENBQXlEOztJQVl6RCx5Q0FBNkU7Ozs7OztJQUs3RSwyQ0FBMEM7O0lBRTFDLGdDQUFjOztJQUNkLG9DQUF5Qjs7SUFDekIscUNBQWtCOztJQUNsQixxQ0FBa0I7O0lBR2xCLHNDQVFFOztJQUdGLDJDQU1FOztJQUVGLDBDQU1FOztJQUVGLHFDQUE0Qjs7SUFDNUIsc0NBQTZCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgSW5wdXQsXHJcbiAgT3V0cHV0LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBPbkNoYW5nZXMsXHJcbiAgZm9yd2FyZFJlZixcclxuICBPbkluaXQsXHJcbiAgVmlld0NoaWxkXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbnRyb2xDb250YWluZXIsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOZ0Zvcm0sIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Jhc2UnO1xyXG5pbXBvcnQgeyBHZW9BZGRyZXNzUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZ2VvY29kZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IEFkZHJlc3MgfSBmcm9tICcuLi8uLi9tb2RlbHMvYWRkcmVzcy5tb2RlbCc7XHJcbmltcG9ydCB7IENvdW50cnlMaXN0LCBDQU5BREEsIENPVU5UUllfTElTVCB9IGZyb20gJy4uL2NvdW50cnkvY291bnRyeS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBQcm92aW5jZUxpc3QsIEJSSVRJU0hfQ09MVU1CSUEsIFBST1ZJTkNFX0xJU1QgfSBmcm9tICcuLi9wcm92aW5jZS9wcm92aW5jZS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDaXR5Q29tcG9uZW50IH0gZnJvbSAnLi4vY2l0eS9jaXR5LmNvbXBvbmVudCc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEFkZHJMYWJlbExpc3Qge1xyXG4gIGFkZHJlc3MxPzogc3RyaW5nO1xyXG4gIGFkZHJlc3MyPzogc3RyaW5nO1xyXG4gIGFkZHJlc3MzPzogc3RyaW5nO1xyXG4gIGNpdHk/OiBzdHJpbmc7XHJcbiAgcHJvdmluY2U/OiBzdHJpbmc7XHJcbiAgY291bnRyeT86IHN0cmluZztcclxuICBwb3N0YWxDb2RlPzogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE1heGxlbmd0aHMge1xyXG4gIGFkZHJlc3M/OiBzdHJpbmc7XHJcbiAgY2l0eT86IHN0cmluZztcclxuICBwcm92aW5jZT86IHN0cmluZztcclxuICBjb3VudHJ5Pzogc3RyaW5nO1xyXG4gIHBvc3RhbENvZGU/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVhZE9ubHlGaWVsZHMge1xyXG4gIGFkZHJlc3M/OiBib29sZWFuO1xyXG4gIGNpdHk/OiBib29sZWFuO1xyXG4gIHByb3ZpbmNlPzogYm9vbGVhbjtcclxuICBjb3VudHJ5PzogYm9vbGVhbjtcclxuICBwb3N0YWxDb2RlPzogYm9vbGVhbjtcclxufVxyXG5cclxuLyoqXHJcbiAqXHJcbiAqIE5vdGUgLSBUaGlzIGNvbXBvbmVudCBSRVFVSVJFUyB0aGF0IGBIdHRwQ2xpZW50TW9kdWxlYCBpcyByZWdpc3RlcmVkIGluIHlvdXIgTmdNb2R1bGUuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2NvbW1vbi1hZGRyZXNzJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vYWRkcmVzcy5jb21wb25lbnQuaHRtbCcsXHJcbiAgLyogUmUtdXNlIHRoZSBzYW1lIG5nRm9ybSB0aGF0IGl0J3MgcGFyZW50IGlzIHVzaW5nLiBUaGUgY29tcG9uZW50IHdpbGwgc2hvd1xyXG4gICAqIHVwIGluIGl0cyBwYXJlbnRzIGB0aGlzLmZvcm1gLCBhbmQgd2lsbCBhdXRvLXVwZGF0ZSBgdGhpcy5mb3JtLnZhbGlkYFxyXG4gICAqL1xyXG4gIHZpZXdQcm92aWRlcnM6IFtcclxuICAgIHsgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lciwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmdGb3JtKSB9XHJcbiAgXSxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHsgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IEFkZHJlc3NDb21wb25lbnQpIH1cclxuICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBZGRyZXNzQ29tcG9uZW50IGV4dGVuZHMgQmFzZVxyXG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcclxuXHJcbiAgLyogRGlzYWJsZSBhbGwgZmllbGRzIGJ5IHNlbmRpbmcgaW4gYm9vbGVhbixcclxuICAgKiBkaXNhYmxlIHNwZWNpZmljIGZpZWxkcyBieSBzZW5kaW5nIGluIFJlYWRPbmx5RmllbGRzIHN0cnVjdHVyZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuIHwgUmVhZE9ubHlGaWVsZHMgPSBmYWxzZTtcclxuICBASW5wdXQoKSBpc1JlcXVpcmVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgY291bnRyeUxpc3Q6IENvdW50cnlMaXN0W10gPSBDT1VOVFJZX0xJU1Q7XHJcbiAgQElucHV0KCkgZGVmYXVsdENvdW50cnk6IHN0cmluZyA9IENBTkFEQTtcclxuICBASW5wdXQoKSBwcm92aW5jZUxpc3Q6IFByb3ZpbmNlTGlzdFtdID0gUFJPVklOQ0VfTElTVDtcclxuICBASW5wdXQoKSBkZWZhdWx0UHJvdmluY2U6IHN0cmluZyA9IEJSSVRJU0hfQ09MVU1CSUE7XHJcbiAgQElucHV0KCkgZGlzYWJsZUdlb2NvZGVyOiBib29sZWFuID0gZmFsc2U7IC8vIFRoaXMgc2hvdWxkIGV2ZW50dWFsbHkgYmUgcmVmYWN0b3JlZCB0byBgZGlzYWJsZUFkZHJlc3NWYWxpZGF0b3JgLiBMZWF2aW5nIGl0IGZvciBjb21wYXRpYmlsaXR5LlxyXG4gIEBJbnB1dCgpIGxhYmVsczogQWRkckxhYmVsTGlzdDtcclxuICBASW5wdXQoKSBtYXhsZW5ndGhzOiBNYXhsZW5ndGhzO1xyXG4gIEBJbnB1dCgpIGJjT25seTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGFkZHJlc3NTZXJ2aWNlVXJsOiBzdHJpbmc7XHJcbiAgQFZpZXdDaGlsZCgnY2l0eScpIHByaXZhdGUgX2NpdHlDb21wb25lbnQ6IENpdHlDb21wb25lbnQ7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGFkZHJlc3ModmFsOiBBZGRyZXNzKSB7XHJcbiAgICBpZiAodmFsKSB7XHJcbiAgICAgIHRoaXMuYWRkciA9IHZhbDtcclxuICAgIH1cclxuICB9XHJcbiAgZ2V0IGFkZHJlc3MoKTogQWRkcmVzcyB7XHJcbiAgICByZXR1cm4gdGhpcy5hZGRyO1xyXG4gIH1cclxuXHJcbiAgQE91dHB1dCgpIGFkZHJlc3NDaGFuZ2U6IEV2ZW50RW1pdHRlcjxBZGRyZXNzPiA9IG5ldyBFdmVudEVtaXR0ZXI8QWRkcmVzcz4oKTtcclxuICAvKipcclxuICAgKiBJZiB0cnVlLCBhZGRzIGEgcGx1cyBpY29uIG5leHQgdG8gc3RyZWV0IGFuZCBlbmFibGVzIHVzZXJzIHRvIGFkZCBhIHNlY29uZFxyXG4gICAqIGFkZHJlc3MgbGluZS4gIFRoaXMgdmFsdWUgYmluZHMgdG8gYGFkZHJlc3MuYWRkcmVzc0xpbmUyYFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGFsbG93RXh0cmFsaW5lczogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBhZGRyOiBBZGRyZXNzO1xyXG4gIHByb3ZMaXN0OiBQcm92aW5jZUxpc3RbXTtcclxuICBzaG93TGluZTIgP