angular6-json-schema-form
Version:
Angular JSON Schema Form builder
510 lines • 75.9 kB
JavaScript
import * as tslib_1 from "tslib";
import cloneDeep from 'lodash-es/cloneDeep';
import filter from 'lodash-es/filter';
import map from 'lodash-es/map';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
import { forEach, hasOwn } from './utility.functions';
import { getControlValidators, removeRecursiveReferences } from './json-schema.functions';
import { hasValue, inArray, isArray, isDate, isDefined, isEmpty, isObject, isPrimitive, toJavaScriptType, toSchemaType } from './validator.functions';
import { JsonPointer } from './jsonpointer.functions';
import { JsonValidators } from './json.validators';
/**
* FormGroup function library:
*
* buildFormGroupTemplate: Builds a FormGroupTemplate from schema
*
* buildFormGroup: Builds an Angular FormGroup from a FormGroupTemplate
*
* mergeValues:
*
* setRequiredFields:
*
* formatFormData:
*
* getControl:
*
* ---- TODO: ----
* TODO: add buildFormGroupTemplateFromLayout function
* buildFormGroupTemplateFromLayout: Builds a FormGroupTemplate from a form layout
*/
/**
* 'buildFormGroupTemplate' function
*
* Builds a template for an Angular FormGroup from a JSON Schema.
*
* TODO: add support for pattern properties
* https://spacetelescope.github.io/understanding-json-schema/reference/object.html
*
* // {any} jsf -
* // {any = null} nodeValue -
* // {boolean = true} mapArrays -
* // {string = ''} schemaPointer -
* // {string = ''} dataPointer -
* // {any = ''} templatePointer -
* // {any} -
*/
export function buildFormGroupTemplate(jsf, nodeValue, setValues, schemaPointer, dataPointer, templatePointer) {
if (nodeValue === void 0) { nodeValue = null; }
if (setValues === void 0) { setValues = true; }
if (schemaPointer === void 0) { schemaPointer = ''; }
if (dataPointer === void 0) { dataPointer = ''; }
if (templatePointer === void 0) { templatePointer = ''; }
var schema = JsonPointer.get(jsf.schema, schemaPointer);
if (setValues) {
if (!isDefined(nodeValue) && (jsf.formOptions.setSchemaDefaults === true ||
(jsf.formOptions.setSchemaDefaults === 'auto' && isEmpty(jsf.formValues)))) {
nodeValue = JsonPointer.get(jsf.schema, schemaPointer + '/default');
}
}
else {
nodeValue = null;
}
// TODO: If nodeValue still not set, check layout for default value
var schemaType = JsonPointer.get(schema, '/type');
var controlType = (hasOwn(schema, 'properties') || hasOwn(schema, 'additionalProperties')) &&
schemaType === 'object' ? 'FormGroup' :
(hasOwn(schema, 'items') || hasOwn(schema, 'additionalItems')) &&
schemaType === 'array' ? 'FormArray' :
!schemaType && hasOwn(schema, '$ref') ? '$ref' : 'FormControl';
var shortDataPointer = removeRecursiveReferences(dataPointer, jsf.dataRecursiveRefMap, jsf.arrayMap);
if (!jsf.dataMap.has(shortDataPointer)) {
jsf.dataMap.set(shortDataPointer, new Map());
}
var nodeOptions = jsf.dataMap.get(shortDataPointer);
if (!nodeOptions.has('schemaType')) {
nodeOptions.set('schemaPointer', schemaPointer);
nodeOptions.set('schemaType', schema.type);
if (schema.format) {
nodeOptions.set('schemaFormat', schema.format);
if (!schema.type) {
nodeOptions.set('schemaType', 'string');
}
}
if (controlType) {
nodeOptions.set('templatePointer', templatePointer);
nodeOptions.set('templateType', controlType);
}
}
var controls;
var validators = getControlValidators(schema);
switch (controlType) {
case 'FormGroup':
controls = {};
if (hasOwn(schema, 'ui:order') || hasOwn(schema, 'properties')) {
var propertyKeys_1 = schema['ui:order'] || Object.keys(schema.properties);
if (propertyKeys_1.includes('*') && !hasOwn(schema.properties, '*')) {
var unnamedKeys = Object.keys(schema.properties)
.filter(function (key) { return !propertyKeys_1.includes(key); });
for (var i = propertyKeys_1.length - 1; i >= 0; i--) {
if (propertyKeys_1[i] === '*') {
propertyKeys_1.splice.apply(propertyKeys_1, tslib_1.__spread([i, 1], unnamedKeys));
}
}
}
propertyKeys_1
.filter(function (key) { return hasOwn(schema.properties, key) ||
hasOwn(schema, 'additionalProperties'); })
.forEach(function (key) { return controls[key] = buildFormGroupTemplate(jsf, JsonPointer.get(nodeValue, [key]), setValues, schemaPointer + (hasOwn(schema.properties, key) ?
'/properties/' + key : '/additionalProperties'), dataPointer + '/' + key, templatePointer + '/controls/' + key); });
jsf.formOptions.fieldsRequired = setRequiredFields(schema, controls);
}
return { controlType: controlType, controls: controls, validators: validators };
case 'FormArray':
controls = [];
var minItems = Math.max(schema.minItems || 0, nodeOptions.get('minItems') || 0);
var maxItems = Math.min(schema.maxItems || 1000, nodeOptions.get('maxItems') || 1000);
var additionalItemsPointer = null;
if (isArray(schema.items)) { // 'items' is an array = tuple items
var tupleItems = nodeOptions.get('tupleItems') ||
(isArray(schema.items) ? Math.min(schema.items.length, maxItems) : 0);
for (var i = 0; i < tupleItems; i++) {
if (i < minItems) {
controls.push(buildFormGroupTemplate(jsf, isArray(nodeValue) ? nodeValue[i] : nodeValue, setValues, schemaPointer + '/items/' + i, dataPointer + '/' + i, templatePointer + '/controls/' + i));
}
else {
var schemaRefPointer = removeRecursiveReferences(schemaPointer + '/items/' + i, jsf.schemaRecursiveRefMap);
var itemRefPointer = removeRecursiveReferences(shortDataPointer + '/' + i, jsf.dataRecursiveRefMap, jsf.arrayMap);
var itemRecursive = itemRefPointer !== shortDataPointer + '/' + i;
if (!hasOwn(jsf.templateRefLibrary, itemRefPointer)) {
jsf.templateRefLibrary[itemRefPointer] = null;
jsf.templateRefLibrary[itemRefPointer] = buildFormGroupTemplate(jsf, null, setValues, schemaRefPointer, itemRefPointer, templatePointer + '/controls/' + i);
}
controls.push(isArray(nodeValue) ?
buildFormGroupTemplate(jsf, nodeValue[i], setValues, schemaPointer + '/items/' + i, dataPointer + '/' + i, templatePointer + '/controls/' + i) :
itemRecursive ?
null : cloneDeep(jsf.templateRefLibrary[itemRefPointer]));
}
}
// If 'additionalItems' is an object = additional list items (after tuple items)
if (schema.items.length < maxItems && isObject(schema.additionalItems)) {
additionalItemsPointer = schemaPointer + '/additionalItems';
}
// If 'items' is an object = list items only (no tuple items)
}
else {
additionalItemsPointer = schemaPointer + '/items';
}
if (additionalItemsPointer) {
var schemaRefPointer = removeRecursiveReferences(additionalItemsPointer, jsf.schemaRecursiveRefMap);
var itemRefPointer = removeRecursiveReferences(shortDataPointer + '/-', jsf.dataRecursiveRefMap, jsf.arrayMap);
var itemRecursive = itemRefPointer !== shortDataPointer + '/-';
if (!hasOwn(jsf.templateRefLibrary, itemRefPointer)) {
jsf.templateRefLibrary[itemRefPointer] = null;
jsf.templateRefLibrary[itemRefPointer] = buildFormGroupTemplate(jsf, null, setValues, schemaRefPointer, itemRefPointer, templatePointer + '/controls/-');
}
// const itemOptions = jsf.dataMap.get(itemRefPointer) || new Map();
var itemOptions = nodeOptions;
if (!itemRecursive || hasOwn(validators, 'required')) {
var arrayLength = Math.min(Math.max(itemRecursive ? 0 :
(itemOptions.get('tupleItems') + itemOptions.get('listItems')) || 0, isArray(nodeValue) ? nodeValue.length : 0), maxItems);
for (var i = controls.length; i < arrayLength; i++) {
controls.push(isArray(nodeValue) ?
buildFormGroupTemplate(jsf, nodeValue[i], setValues, schemaRefPointer, dataPointer + '/-', templatePointer + '/controls/-') :
itemRecursive ?
null : cloneDeep(jsf.templateRefLibrary[itemRefPointer]));
}
}
}
return { controlType: controlType, controls: controls, validators: validators };
case '$ref':
var schemaRef = JsonPointer.compile(schema.$ref);
var dataRef = JsonPointer.toDataPointer(schemaRef, schema);
var refPointer = removeRecursiveReferences(dataRef, jsf.dataRecursiveRefMap, jsf.arrayMap);
if (refPointer && !hasOwn(jsf.templateRefLibrary, refPointer)) {
// Set to null first to prevent recursive reference from causing endless loop
jsf.templateRefLibrary[refPointer] = null;
var newTemplate = buildFormGroupTemplate(jsf, setValues, setValues, schemaRef);
if (newTemplate) {
jsf.templateRefLibrary[refPointer] = newTemplate;
}
else {
delete jsf.templateRefLibrary[refPointer];
}
}
return null;
case 'FormControl':
var value = {
value: setValues && isPrimitive(nodeValue) ? nodeValue : null,
disabled: nodeOptions.get('disabled') || false
};
return { controlType: controlType, value: value, validators: validators };
default:
return null;
}
}
/**
* 'buildFormGroup' function
*
* // {any} template -
* // {AbstractControl}
*/
export function buildFormGroup(template) {
var validatorFns = [];
var validatorFn = null;
if (hasOwn(template, 'validators')) {
forEach(template.validators, function (parameters, validator) {
if (typeof JsonValidators[validator] === 'function') {
validatorFns.push(JsonValidators[validator].apply(null, parameters));
}
});
if (validatorFns.length &&
inArray(template.controlType, ['FormGroup', 'FormArray'])) {
validatorFn = validatorFns.length > 1 ?
JsonValidators.compose(validatorFns) : validatorFns[0];
}
}
if (hasOwn(template, 'controlType')) {
switch (template.controlType) {
case 'FormGroup':
var groupControls_1 = {};
forEach(template.controls, function (controls, key) {
var newControl = buildFormGroup(controls);
if (newControl) {
groupControls_1[key] = newControl;
}
});
return new FormGroup(groupControls_1, validatorFn);
case 'FormArray':
return new FormArray(filter(map(template.controls, function (controls) { return buildFormGroup(controls); })), validatorFn);
case 'FormControl':
return new FormControl(template.value, validatorFns);
}
}
return null;
}
/**
* 'mergeValues' function
*
* // {any[]} ...valuesToMerge - Multiple values to merge
* // {any} - Merged values
*/
export function mergeValues() {
var e_1, _a, e_2, _b, e_3, _c;
var valuesToMerge = [];
for (var _i = 0; _i < arguments.length; _i++) {
valuesToMerge[_i] = arguments[_i];
}
var mergedValues = null;
try {
for (var valuesToMerge_1 = tslib_1.__values(valuesToMerge), valuesToMerge_1_1 = valuesToMerge_1.next(); !valuesToMerge_1_1.done; valuesToMerge_1_1 = valuesToMerge_1.next()) {
var currentValue = valuesToMerge_1_1.value;
if (!isEmpty(currentValue)) {
if (typeof currentValue === 'object' &&
(isEmpty(mergedValues) || typeof mergedValues !== 'object')) {
if (isArray(currentValue)) {
mergedValues = tslib_1.__spread(currentValue);
}
else if (isObject(currentValue)) {
mergedValues = tslib_1.__assign({}, currentValue);
}
}
else if (typeof currentValue !== 'object') {
mergedValues = currentValue;
}
else if (isObject(mergedValues) && isObject(currentValue)) {
Object.assign(mergedValues, currentValue);
}
else if (isObject(mergedValues) && isArray(currentValue)) {
var newValues = [];
try {
for (var currentValue_1 = tslib_1.__values(currentValue), currentValue_1_1 = currentValue_1.next(); !currentValue_1_1.done; currentValue_1_1 = currentValue_1.next()) {
var value = currentValue_1_1.value;
newValues.push(mergeValues(mergedValues, value));
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (currentValue_1_1 && !currentValue_1_1.done && (_b = currentValue_1.return)) _b.call(currentValue_1);
}
finally { if (e_2) throw e_2.error; }
}
mergedValues = newValues;
}
else if (isArray(mergedValues) && isObject(currentValue)) {
var newValues = [];
try {
for (var mergedValues_1 = tslib_1.__values(mergedValues), mergedValues_1_1 = mergedValues_1.next(); !mergedValues_1_1.done; mergedValues_1_1 = mergedValues_1.next()) {
var value = mergedValues_1_1.value;
newValues.push(mergeValues(value, currentValue));
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (mergedValues_1_1 && !mergedValues_1_1.done && (_c = mergedValues_1.return)) _c.call(mergedValues_1);
}
finally { if (e_3) throw e_3.error; }
}
mergedValues = newValues;
}
else if (isArray(mergedValues) && isArray(currentValue)) {
var newValues = [];
for (var i = 0; i < Math.max(mergedValues.length, currentValue.length); i++) {
if (i < mergedValues.length && i < currentValue.length) {
newValues.push(mergeValues(mergedValues[i], currentValue[i]));
}
else if (i < mergedValues.length) {
newValues.push(mergedValues[i]);
}
else if (i < currentValue.length) {
newValues.push(currentValue[i]);
}
}
mergedValues = newValues;
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (valuesToMerge_1_1 && !valuesToMerge_1_1.done && (_a = valuesToMerge_1.return)) _a.call(valuesToMerge_1);
}
finally { if (e_1) throw e_1.error; }
}
return mergedValues;
}
/**
* 'setRequiredFields' function
*
* // {schema} schema - JSON Schema
* // {object} formControlTemplate - Form Control Template object
* // {boolean} - true if any fields have been set to required, false if not
*/
export function setRequiredFields(schema, formControlTemplate) {
var fieldsRequired = false;
if (hasOwn(schema, 'required') && !isEmpty(schema.required)) {
fieldsRequired = true;
var requiredArray = isArray(schema.required) ? schema.required : [schema.required];
requiredArray = forEach(requiredArray, function (key) { return JsonPointer.set(formControlTemplate, '/' + key + '/validators/required', []); });
}
return fieldsRequired;
// TODO: Add support for patternProperties
// https://spacetelescope.github.io/understanding-json-schema/reference/object.html#pattern-properties
}
/**
* 'formatFormData' function
*
* // {any} formData - Angular FormGroup data object
* // {Map<string, any>} dataMap -
* // {Map<string, string>} recursiveRefMap -
* // {Map<string, number>} arrayMap -
* // {boolean = false} fixErrors - if TRUE, tries to fix data
* // {any} - formatted data object
*/
export function formatFormData(formData, dataMap, recursiveRefMap, arrayMap, returnEmptyFields, fixErrors) {
if (returnEmptyFields === void 0) { returnEmptyFields = false; }
if (fixErrors === void 0) { fixErrors = false; }
if (formData === null || typeof formData !== 'object') {
return formData;
}
var formattedData = isArray(formData) ? [] : {};
JsonPointer.forEachDeep(formData, function (value, dataPointer) {
// If returnEmptyFields === true,
// add empty arrays and objects to all allowed keys
if (returnEmptyFields && isArray(value)) {
JsonPointer.set(formattedData, dataPointer, []);
}
else if (returnEmptyFields && isObject(value) && !isDate(value)) {
JsonPointer.set(formattedData, dataPointer, {});
}
else {
var genericPointer_1 = JsonPointer.has(dataMap, [dataPointer, 'schemaType']) ? dataPointer :
removeRecursiveReferences(dataPointer, recursiveRefMap, arrayMap);
if (JsonPointer.has(dataMap, [genericPointer_1, 'schemaType'])) {
var schemaType = dataMap.get(genericPointer_1).get('schemaType');
if (schemaType === 'null') {
JsonPointer.set(formattedData, dataPointer, null);
}
else if ((hasValue(value) || returnEmptyFields) &&
inArray(schemaType, ['string', 'integer', 'number', 'boolean'])) {
var newValue = (fixErrors || (value === null && returnEmptyFields)) ?
toSchemaType(value, schemaType) : toJavaScriptType(value, schemaType);
if (isDefined(newValue) || returnEmptyFields) {
JsonPointer.set(formattedData, dataPointer, newValue);
}
// If returnEmptyFields === false,
// only add empty arrays and objects to required keys
}
else if (schemaType === 'object' && !returnEmptyFields) {
(dataMap.get(genericPointer_1).get('required') || []).forEach(function (key) {
var keySchemaType = dataMap.get(genericPointer_1 + "/" + key).get('schemaType');
if (keySchemaType === 'array') {
JsonPointer.set(formattedData, dataPointer + "/" + key, []);
}
else if (keySchemaType === 'object') {
JsonPointer.set(formattedData, dataPointer + "/" + key, {});
}
});
}
// Finish incomplete 'date-time' entries
if (dataMap.get(genericPointer_1).get('schemaFormat') === 'date-time') {
// "2000-03-14T01:59:26.535" -> "2000-03-14T01:59:26.535Z" (add "Z")
if (/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?$/i.test(value)) {
JsonPointer.set(formattedData, dataPointer, value + "Z");
// "2000-03-14T01:59" -> "2000-03-14T01:59:00Z" (add ":00Z")
}
else if (/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d$/i.test(value)) {
JsonPointer.set(formattedData, dataPointer, value + ":00Z");
// "2000-03-14" -> "2000-03-14T00:00:00Z" (add "T00:00:00Z")
}
else if (fixErrors && /^\d\d\d\d-[0-1]\d-[0-3]\d$/i.test(value)) {
JsonPointer.set(formattedData, dataPointer, value + ":00:00:00Z");
}
}
}
else if (typeof value !== 'object' || isDate(value) ||
(value === null && returnEmptyFields)) {
console.error('formatFormData error: ' +
("Schema type not found for form value at " + genericPointer_1));
console.error('dataMap', dataMap);
console.error('recursiveRefMap', recursiveRefMap);
console.error('genericPointer', genericPointer_1);
}
}
});
return formattedData;
}
/**
* 'getControl' function
*
* Uses a JSON Pointer for a data object to retrieve a control from
* an Angular formGroup or formGroup template. (Note: though a formGroup
* template is much simpler, its basic structure is idential to a formGroup).
*
* If the optional third parameter 'returnGroup' is set to TRUE, the group
* containing the control is returned, rather than the control itself.
*
* // {FormGroup} formGroup - Angular FormGroup to get value from
* // {Pointer} dataPointer - JSON Pointer (string or array)
* // {boolean = false} returnGroup - If true, return group containing control
* // {group} - Located value (or null, if no control found)
*/
export function getControl(formGroup, dataPointer, returnGroup) {
var e_4, _a;
if (returnGroup === void 0) { returnGroup = false; }
if (!isObject(formGroup) || !JsonPointer.isJsonPointer(dataPointer)) {
if (!JsonPointer.isJsonPointer(dataPointer)) {
// If dataPointer input is not a valid JSON pointer, check to
// see if it is instead a valid object path, using dot notaion
if (typeof dataPointer === 'string') {
var formControl = formGroup.get(dataPointer);
if (formControl) {
return formControl;
}
}
console.error("getControl error: Invalid JSON Pointer: " + dataPointer);
}
if (!isObject(formGroup)) {
console.error("getControl error: Invalid formGroup: " + formGroup);
}
return null;
}
var dataPointerArray = JsonPointer.parse(dataPointer);
if (returnGroup) {
dataPointerArray = dataPointerArray.slice(0, -1);
}
// If formGroup input is a real formGroup (not a formGroup template)
// try using formGroup.get() to return the control
if (typeof formGroup.get === 'function' &&
dataPointerArray.every(function (key) { return key.indexOf('.') === -1; })) {
var formControl = formGroup.get(dataPointerArray.join('.'));
if (formControl) {
return formControl;
}
}
// If formGroup input is a formGroup template,
// or formGroup.get() failed to return the control,
// search the formGroup object for dataPointer's control
var subGroup = formGroup;
try {
for (var dataPointerArray_1 = tslib_1.__values(dataPointerArray), dataPointerArray_1_1 = dataPointerArray_1.next(); !dataPointerArray_1_1.done; dataPointerArray_1_1 = dataPointerArray_1.next()) {
var key = dataPointerArray_1_1.value;
if (hasOwn(subGroup, 'controls')) {
subGroup = subGroup.controls;
}
if (isArray(subGroup) && (key === '-')) {
subGroup = subGroup[subGroup.length - 1];
}
else if (hasOwn(subGroup, key)) {
subGroup = subGroup[key];
}
else {
console.error("getControl error: Unable to find \"" + key + "\" item in FormGroup.");
console.error(dataPointer);
console.error(formGroup);
return;
}
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (dataPointerArray_1_1 && !dataPointerArray_1_1.done && (_a = dataPointerArray_1.return)) _a.call(dataPointerArray_1);
}
finally { if (e_4) throw e_4.error; }
}
return subGroup;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1ncm91cC5mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyNi1qc29uLXNjaGVtYS1mb3JtLyIsInNvdXJjZXMiOlsibGliL3NoYXJlZC9mb3JtLWdyb3VwLmZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxTQUFTLE1BQU0scUJBQXFCLENBQUM7QUFDNUMsT0FBTyxNQUFNLE1BQU0sa0JBQWtCLENBQUM7QUFDdEMsT0FBTyxHQUFHLE1BQU0sZUFBZSxDQUFDO0FBQ2hDLE9BQU8sRUFFTCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFNBQVMsRUFFUixNQUFNLGdCQUFnQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLHlCQUF5QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUYsT0FBTyxFQUNMLFFBQVEsRUFDUixPQUFPLEVBQ1AsT0FBTyxFQUNQLE1BQU0sRUFDTixTQUFTLEVBQ1QsT0FBTyxFQUNQLFFBQVEsRUFDUixXQUFXLEVBRVgsZ0JBQWdCLEVBQ2hCLFlBQVksRUFDWCxNQUFNLHVCQUF1QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxXQUFXLEVBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFJbkQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUVIOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FDcEMsR0FBUSxFQUFFLFNBQXFCLEVBQUUsU0FBZ0IsRUFDakQsYUFBa0IsRUFBRSxXQUFnQixFQUFFLGVBQW9CO0lBRGhELDBCQUFBLEVBQUEsZ0JBQXFCO0lBQUUsMEJBQUEsRUFBQSxnQkFBZ0I7SUFDakQsOEJBQUEsRUFBQSxrQkFBa0I7SUFBRSw0QkFBQSxFQUFBLGdCQUFnQjtJQUFFLGdD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cUJBQUEsaUJBQUEsZ0JBQWdCLENBQUEsa0RBQUEsZ0ZBQUU7WUFBL0IsSUFBTSxHQUFHLDZCQUFBO1lBQ1osSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxFQUFFO2dCQUFFLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDO2FBQUU7WUFDbkUsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLEVBQUU7Z0JBQ3RDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQzthQUMxQztpQkFBTSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ2hDLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDMUI7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLEtBQUssQ0FBQyx3Q0FBcUMsR0FBRywwQkFBc0IsQ0FBQyxDQUFDO2dCQUM5RSxPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUMzQixPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUN6QixPQUFPO2FBQ1I7U0FDRjs7Ozs7Ozs7O0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjbG9uZURlZXAgZnJvbSAnbG9kYXNoLWVzL2Nsb25lRGVlcCc7XG5pbXBvcnQgZmlsdGVyIGZyb20gJ2xvZGFzaC1lcy9maWx0ZXInO1xuaW1wb3J0IG1hcCBmcm9tICdsb2Rhc2gtZXMvbWFwJztcbmltcG9ydCB7XG4gIEFic3RyYWN0Q29udHJvbCxcbiAgRm9ybUFycmF5LFxuICBGb3JtQ29udHJvbCxcbiAgRm9ybUdyb3VwLFxuICBWYWxpZGF0b3JGblxuICB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGZvckVhY2gsIGhhc093biB9IGZyb20gJy4vdXRpbGl0eS5mdW5jdGlvbnMnO1xuaW1wb3J0IHsgZ2V0Q29udHJvbFZhbGlkYXRvcnMsIHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMgfSBmcm9tICcuL2pzb24tc2NoZW1hLmZ1bmN0aW9ucyc7XG5pbXBvcnQge1xuICBoYXNWYWx1ZSxcbiAgaW5BcnJheSxcbiAgaXNBcnJheSxcbiAgaXNEYXRlLFxuICBpc0RlZmluZWQsXG4gIGlzRW1wdHksXG4gIGlzT2JqZWN0LFxuICBpc1ByaW1pdGl2ZSxcbiAgU2NoZW1hUHJpbWl0aXZlVHlwZSxcbiAgdG9KYXZhU2NyaXB0VHlwZSxcbiAgdG9TY2hlbWFUeXBlXG4gIH0gZnJvbSAnLi92YWxpZGF0b3IuZnVuY3Rpb25zJztcbmltcG9ydCB7IEpzb25Qb2ludGVyLCBQb2ludGVyIH0gZnJvbSAnLi9qc29ucG9pbnRlci5mdW5jdGlvbnMnO1xuaW1wb3J0IHsgSnNvblZhbGlkYXRvcnMgfSBmcm9tICcuL2pzb24udmFsaWRhdG9ycyc7XG5cblxuXG4vKipcbiAqIEZvcm1Hcm91cCBmdW5jdGlvbiBsaWJyYXJ5OlxuICpcbiAqIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGU6ICBCdWlsZHMgYSBGb3JtR3JvdXBUZW1wbGF0ZSBmcm9tIHNjaGVtYVxuICpcbiAqIGJ1aWxkRm9ybUdyb3VwOiAgICAgICAgICBCdWlsZHMgYW4gQW5ndWxhciBGb3JtR3JvdXAgZnJvbSBhIEZvcm1Hcm91cFRlbXBsYXRlXG4gKlxuICogbWVyZ2VWYWx1ZXM6XG4gKlxuICogc2V0UmVxdWlyZWRGaWVsZHM6XG4gKlxuICogZm9ybWF0Rm9ybURhdGE6XG4gKlxuICogZ2V0Q29udHJvbDpcbiAqXG4gKiAtLS0tIFRPRE86IC0tLS1cbiAqIFRPRE86IGFkZCBidWlsZEZvcm1Hcm91cFRlbXBsYXRlRnJvbUxheW91dCBmdW5jdGlvblxuICogYnVpbGRGb3JtR3JvdXBUZW1wbGF0ZUZyb21MYXlvdXQ6IEJ1aWxkcyBhIEZvcm1Hcm91cFRlbXBsYXRlIGZyb20gYSBmb3JtIGxheW91dFxuICovXG5cbi8qKlxuICogJ2J1aWxkRm9ybUdyb3VwVGVtcGxhdGUnIGZ1bmN0aW9uXG4gKlxuICogQnVpbGRzIGEgdGVtcGxhdGUgZm9yIGFuIEFuZ3VsYXIgRm9ybUdyb3VwIGZyb20gYSBKU09OIFNjaGVtYS5cbiAqXG4gKiBUT0RPOiBhZGQgc3VwcG9ydCBmb3IgcGF0dGVybiBwcm9wZXJ0aWVzXG4gKiBodHRwczovL3NwYWNldGVsZXNjb3BlLmdpdGh1Yi5pby91bmRlcnN0YW5kaW5nLWpzb24tc2NoZW1hL3JlZmVyZW5jZS9vYmplY3QuaHRtbFxuICpcbiAqIC8vICB7YW55fSBqc2YgLVxuICogLy8gIHthbnkgPSBudWxsfSBub2RlVmFsdWUgLVxuICogLy8gIHtib29sZWFuID0gdHJ1ZX0gbWFwQXJyYXlzIC1cbiAqIC8vICB7c3RyaW5nID0gJyd9IHNjaGVtYVBvaW50ZXIgLVxuICogLy8gIHtzdHJpbmcgPSAnJ30gZGF0YVBvaW50ZXIgLVxuICogLy8gIHthbnkgPSAnJ30gdGVtcGxhdGVQb2ludGVyIC1cbiAqIC8vIHthbnl9IC1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGUoXG4gIGpzZjogYW55LCBub2R