UNPKG

@ng-flexy/form

Version:

Flexy components and tools to build Angular 8+ applications

2,022 lines 81.9 kB
import * as i0 from '@angular/core';
import { Input, Directive, InjectionToken, Optional, Inject, Injectable, Component, EventEmitter, Output, Pipe, NgModule } from '@angular/core';
import * as jsonata_ from 'jsonata';
import { uniq, set, merge, has, get, cloneDeep, template } from 'lodash';
import { skip, debounceTime, map } from 'rxjs/operators';
import * as i2 from '@angular/forms';
import { FormControl, FormArray, Validators, FormGroup, AbstractControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i1 from '@ng-flexy/layout';
import { FlexyLayout, FlexyLayoutModule } from '@ng-flexy/layout';
import { BehaviorSubject } from 'rxjs';
import * as i2$1 from '@ng-flexy/core';
import * as i1$1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i1$2 from '@ngx-translate/core';
import { TranslateModule } from '@ngx-translate/core';
import * as i1$3 from '@angular/common/http';

const jsonata$4 = jsonata_;
function bindAttributes(schema, nativeEl, renderer, data) {
    if (nativeEl && renderer && schema.attributes) {
        Object.keys(schema.attributes).forEach(attrKey => {
            if (typeof schema.attributes[attrKey] === 'object') {
                const attrValues = [];
                Object.keys(schema.attributes[attrKey]).forEach(oKey => {
                    if (schema.attributes[attrKey][oKey]) {
                        try {
                            const is = jsonata$4(schema.attributes[attrKey][oKey]).evaluate(data);
                            if (is) {
                                attrValues.push(oKey);
                            }
                        }
                        catch (e) {
                            // do nothing
                        }
                    }
                });
                renderer.setAttribute(nativeEl, attrKey, attrValues.join(' '));
            }
            else if (typeof schema.attributes[attrKey] === 'string') {
                renderer.setAttribute(nativeEl, attrKey, schema.attributes[attrKey]);
            }
        });
    }
}

class FlexyFormAttributesDirective {
    renderer;
    el;
    flexyForm;
    componentSchema;
    _changesSubscription;
    constructor(renderer, el) {
        this.renderer = renderer;
        this.el = el;
    }
    ngOnInit() {
        if (this.componentSchema && this.componentSchema.attributes) {
            bindAttributes(this.componentSchema, this.el.nativeElement, this.renderer, this.flexyForm.currentData);
            this._changesSubscription = this.flexyForm.currentData$.subscribe(data => {
                bindAttributes(this.componentSchema, this.el.nativeElement, this.renderer, data);
            });
        }
    }
    ngOnDestroy() {
        if (this._changesSubscription) {
            this._changesSubscription.unsubscribe();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormAttributesDirective, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: FlexyFormAttributesDirective, isStandalone: false, selector: "[flexyFormAttributes]", inputs: { flexyForm: "flexyForm", componentSchema: "componentSchema" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormAttributesDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[flexyFormAttributes]',
                    standalone: false
                }]
        }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { flexyForm: [{
                type: Input
            }], componentSchema: [{
                type: Input
            }] } });

const LAYOUT_SCHEMA_KEY = 'layoutSchema';
const LAYOUT_FORM_KEY = 'form';
class FlexyFormContainerDirective {
    vc;
    resolver;
    renderer;
    flexyForm;
    set componentSchema(schema) {
        this._schema = schema;
    }
    get componentSchema() {
        return this._schema;
    }
    _schema;
    _changesSubscription;
    _componentRef;
    constructor(vc, resolver, renderer) {
        this.vc = vc;
        this.resolver = resolver;
        this.renderer = renderer;
    }
    ngOnInit() {
        if (!this._schema) {
            return;
        }
        if (!this._schema.componentType) {
            return;
        }
        const componentFactory = this.resolver.resolveComponentFactory(this._schema.componentType);
        const viewContainerRef = this.vc;
        viewContainerRef.clear();
        const componentRef = viewContainerRef.createComponent(componentFactory);
        componentRef.instance[LAYOUT_SCHEMA_KEY] = this._schema;
        componentRef.instance[LAYOUT_FORM_KEY] = this.flexyForm;
        this._schema.componentRef = componentRef;
        if (this._schema.componentInputs) {
            Object.keys(this._schema.componentInputs).forEach(key => {
                componentRef.instance[key] = this._schema.componentInputs[key];
            });
        }
        this._componentRef = componentRef;
        if (this._schema.attributes) {
            bindAttributes(this._schema, this._componentRef.location.nativeElement, this.renderer, this.flexyForm.currentData);
        }
        this._changesSubscription = this.flexyForm.currentData$.subscribe(data => {
            if (this._componentRef) {
                bindAttributes(this.componentSchema, this._componentRef.location.nativeElement, this.renderer, data);
            }
        });
    }
    ngOnDestroy() {
        if (this._changesSubscription) {
            this._changesSubscription.unsubscribe();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormContainerDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.ComponentFactoryResolver }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: FlexyFormContainerDirective, isStandalone: false, selector: "[flexyFormContainer]", inputs: { flexyForm: "flexyForm", componentSchema: "componentSchema" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormContainerDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[flexyFormContainer]',
                    standalone: false
                }]
        }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.ComponentFactoryResolver }, { type: i0.Renderer2 }], propDecorators: { flexyForm: [{
                type: Input
            }], componentSchema: [{
                type: Input
            }] } });

const COMPLEX_TYPE_INDEX_MARKER = '{%}';
var FlexyFormFieldType;
(function (FlexyFormFieldType) {
    FlexyFormFieldType["String"] = "string";
    FlexyFormFieldType["Number"] = "number";
    FlexyFormFieldType["Boolean"] = "boolean";
    FlexyFormFieldType["Array"] = "array";
    FlexyFormFieldType["Group"] = "group";
})(FlexyFormFieldType || (FlexyFormFieldType = {}));

var FlexyFormsValidators;
(function (FlexyFormsValidators) {
    function notEmptyValidator(control) {
        if (!control) {
            return null;
        }
        if (FlexyFormsValidators.isEmpty(control)) {
            return {
                'not-empty': true
            };
        }
        return null;
    }
    FlexyFormsValidators.notEmptyValidator = notEmptyValidator;
    function noWhitespaceValidator(control) {
        if (!control) {
            return null;
        }
        if ((control.value || '').trim().length === 0) {
            return { whitespace: true };
        }
        return null;
    }
    FlexyFormsValidators.noWhitespaceValidator = noWhitespaceValidator;
    function emailValidator(control) {
        if (!control) {
            return null;
        }
        const re = new RegExp([
            '^(([^<>()\\[\\]\\\\.,;:!#\\s@"]+(\\.[^<>()\\[\\]\\\\.,;:!#\\s@"]+)*)|(".+"))@',
            '((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)',
            '+[a-zA-Z]{2,})|([a-zA-Z\\-0-9]+))$'
        ].join(''));
        if (!FlexyFormsValidators.isEmpty(control) && !re.test(control.value)) {
            return {
                'invalid-email': {
                    currentValue: control.value
                }
            };
        }
        return null;
    }
    FlexyFormsValidators.emailValidator = emailValidator;
    function booleanValidator(control) {
        if (!control) {
            return null;
        }
        if (!FlexyFormsValidators.isEmpty(control) && typeof control.value !== 'boolean') {
            return {
                'invalid-boolean': {
                    currentValue: control.value
                }
            };
        }
        return null;
    }
    FlexyFormsValidators.booleanValidator = booleanValidator;
    function integerValidator(control) {
        if (!control) {
            return null;
        }
        const re = /^-?\d+$/;
        if (!FlexyFormsValidators.isEmpty(control) && !re.test(control.value)) {
            return {
                'invalid-integer': {
                    currentValue: control.value
                }
            };
        }
        return null;
    }
    FlexyFormsValidators.integerValidator = integerValidator;
    function minValidator(min) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!(min || min === 0)) {
                return {
                    'invalid-min': {
                        wrongConfiguration: true
                    }
                };
            }
            const notNumber = FlexyFormsValidators.numberValidator(control);
            if (notNumber) {
                return notNumber;
            }
            if ((!FlexyFormsValidators.isEmpty(control) || control.value === 0) && control.value < min) {
                return {
                    'invalid-min': {
                        minimumValue: min,
                        currentValue: control.value
                    }
                };
            }
            return null;
        };
    }
    FlexyFormsValidators.minValidator = minValidator;
    function maxValidator(max) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!(max || max === 0)) {
                return {
                    'invalid-max': {
                        wrongConfiguration: true
                    }
                };
            }
            const notNumber = FlexyFormsValidators.numberValidator(control);
            if (notNumber) {
                return notNumber;
            }
            if ((!FlexyFormsValidators.isEmpty(control) || control.value === 0) && control.value > max) {
                return {
                    'invalid-max': {
                        maximumValue: max,
                        currentValue: control.value
                    }
                };
            }
            return null;
        };
    }
    FlexyFormsValidators.maxValidator = maxValidator;
    function numberValidator(control) {
        if (!control) {
            return null;
        }
        const re = /^-?(\d+\.?\d*)$|^(\d*\.?\d+)$/;
        if (!FlexyFormsValidators.isEmpty(control) && !re.test(control.value)) {
            return {
                'invalid-number': {
                    currentValue: control.value
                }
            };
        }
        return null;
    }
    FlexyFormsValidators.numberValidator = numberValidator;
    function minLengthArray(min) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!(min || min === 0)) {
                return {
                    'min-length-array': {
                        wrongConfiguration: true
                    }
                };
            }
            if (control.value && Array.isArray(control.value) && control.value.length >= min) {
                return null;
            }
            return {
                'min-length-array': {
                    minimumLength: min,
                    currentLength: control.value
                }
            };
        };
    }
    FlexyFormsValidators.minLengthArray = minLengthArray;
    function maxLengthArray(max) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!(max || max === 0)) {
                return {
                    'max-length-array': {
                        wrongConfiguration: true
                    }
                };
            }
            if (control.value && control.value.length <= max) {
                return null;
            }
            return {
                'max-length-array': {
                    maximumLength: max,
                    currentLength: control.value
                }
            };
        };
    }
    FlexyFormsValidators.maxLengthArray = maxLengthArray;
    function isEmpty(control) {
        if (!control) {
            return null;
        }
        if (!control.value || (Array.isArray(control.value) && control.value.length === 0)) {
            return true;
        }
        else {
            return false;
        }
    }
    FlexyFormsValidators.isEmpty = isEmpty;
    function urlValidator(control) {
        if (!control) {
            return null;
        }
        const re = new RegExp([
            '((([A-Za-z]{3,9}:(?:\\/\\/)?)(?:[\\-;:&=\\+\\$,\\w]+@)?[A-Za-z0-9\\.\\-]',
            '+|(?:www\\.|[\\-;:&=\\+\\$,\\w]+@)[A-Za-z0-9\\.\\-]+)((?:\\/[\\+~%\\/\\.\\w\\-_]*)?\\??',
            '(?:[\\-\\+=&;%@\\.\\w_]*)#?(?:[\\.\\!\\/\\\\\\w]*))?)'
        ].join(''));
        if (!FlexyFormsValidators.isEmpty(control) && !re.test(control.value)) {
            return {
                'invalid-url': {
                    currentValue: control.value
                }
            };
        }
        return null;
    }
    FlexyFormsValidators.urlValidator = urlValidator;
    function crossFieldValidator(fields) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!(fields && fields.lower && fields.greater)) {
                return {
                    'cross-field-invalid': {
                        wrongConfiguration: true
                    }
                };
            }
            const lower = getControl(fields.lower.path, control);
            const greater = getControl(fields.greater.path, control);
            if (!(greater && greater.valid && lower && lower.valid && greater.value < lower.value)) {
                return null;
            }
            return {
                'cross-field-invalid': {
                    greater: fields.greater.name,
                    greaterPath: fields.greater.path,
                    greaterValue: greater && greater.value,
                    lower: fields.lower.name,
                    lowerPath: fields.lower.path,
                    lowerValue: lower && lower.value
                }
            };
        };
    }
    FlexyFormsValidators.crossFieldValidator = crossFieldValidator;
    function crossFieldMinValidator(minPath) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!minPath) {
                return {
                    'invalid-min': {
                        wrongConfiguration: true
                    }
                };
            }
            const min = getControl(minPath, control);
            if (!(min && control.valid && control.value < min.value)) {
                return null;
            }
            return {
                'invalid-min': {
                    minimumValue: min.value,
                    currentValue: control.value
                }
            };
        };
    }
    FlexyFormsValidators.crossFieldMinValidator = crossFieldMinValidator;
    function crossFieldMaxValidator(maxPath) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!maxPath) {
                return {
                    'invalid-max': {
                        wrongConfiguration: true
                    }
                };
            }
            const max = getControl(maxPath, control);
            if (!(max && control.valid && control.value > max.value)) {
                return null;
            }
            return {
                'invalid-max': {
                    maximumValue: max.value,
                    currentValue: control.value
                }
            };
        };
    }
    FlexyFormsValidators.crossFieldMaxValidator = crossFieldMaxValidator;
    function crossFieldAbsoluteMinValidator(minPath) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!minPath) {
                return {
                    'absolute-min-invalid': {
                        wrongConfiguration: true
                    }
                };
            }
            const min = getControl(minPath, control);
            if (min && control.valid && min.valid && Math.abs(control.value) >= min.value) {
                return null;
            }
            return {
                'absolute-min-invalid': {
                    min: min.value,
                    currentValue: control.value
                }
            };
        };
    }
    FlexyFormsValidators.crossFieldAbsoluteMinValidator = crossFieldAbsoluteMinValidator;
    function forbiddenValuesValidator(forbiddenValues) {
        return (control) => {
            if (!control) {
                return null;
            }
            if (!forbiddenValues) {
                return {
                    'forbidden-value': {
                        wrongConfiguration: true
                    }
                };
            }
            if (!forbiddenValues.includes(control.value)) {
                return null;
            }
            return {
                'forbidden-value': {
                    value: control.value
                }
            };
        };
    }
    FlexyFormsValidators.forbiddenValuesValidator = forbiddenValuesValidator;
    function arrayUniqueFieldsValidator(data) {
        return (control) => {
            if (!control || !control.controls) {
                return null;
            }
            if (!(data && data.path)) {
                return {
                    'value-duplicate': {
                        wrongConfiguration: true
                    }
                };
            }
            const comparedValues = [];
            control.controls.forEach(item => {
                const compared = getControl(data.path, item);
                if (compared) {
                    comparedValues.push(compared.value);
                }
            });
            if (uniq(comparedValues).length === comparedValues.length) {
                return null;
            }
            return {
                'value-duplicate': {
                    field: data.fieldName
                }
            };
        };
    }
    FlexyFormsValidators.arrayUniqueFieldsValidator = arrayUniqueFieldsValidator;
    function getControl(path, control) {
        let arrayPath = [];
        if (Array.isArray(path)) {
            arrayPath = path;
        }
        else if (path) {
            const parents = ('' + path).indexOf('../') !== -1 ? path.split('../') : [path];
            const sPath = '' + parents.pop();
            const stringPath = sPath.split('.').map(i => {
                if (i.match(/^[0-9]+$/)) {
                    return parseInt(i, 10);
                }
                else {
                    return i;
                }
            });
            parents.fill('../');
            parents.push(...stringPath);
            arrayPath = parents;
        }
        arrayPath.forEach(i => {
            if (control && control.parent && i === '../') {
                control = control.parent;
            }
            else if (control && control.controls) {
                control = Number.isInteger(i) ? control.get(Object.keys(control.controls)[i]) : control.controls[i];
            }
        });
        return control;
    }
})(FlexyFormsValidators || (FlexyFormsValidators = {}));

const HIDDEN_IF_GROUP_NAME = '__if__';
const HIDDEN_CALC_GROUP_NAME = '__calc__';
function parseFormJson(json) {
    if (Array.isArray(json)) {
        return parseFormVersion1(json);
    }
    else if (json.schemaVersion === 1) {
        return parseFormVersion1(json.schema);
    }
    else {
        const schema = json.schema;
        assignHiddenNames(schema);
        checkSchema(schema);
        return json.schema;
    }
}
function checkSchema(schema) {
    if (schema && Array.isArray(schema)) {
        schema.forEach((jsonItem, index) => {
            if (jsonItem.if &&
                (jsonItem.name || jsonItem.type)) {
                console.warn('Wrong if schema', jsonItem);
            }
            if (jsonItem.children) {
                checkSchema(jsonItem.children);
            }
        });
    }
}
function assignHiddenNames(schema) {
    if (schema && Array.isArray(schema)) {
        schema.forEach((jsonItem, index) => {
            // if ((jsonItem as FlexyFormIfJsonSchema).if && !(jsonItem as FlexyFormFieldLayoutJsonSchema).type) {
            //   (jsonItem as FlexyFormFieldLayoutJsonSchema).type = FlexyFormFieldType.Group;
            // }
            if (jsonItem.calc && !jsonItem.name) {
                jsonItem.name =
                    HIDDEN_CALC_GROUP_NAME +
                        '.' +
                        (jsonItem.id
                            ? jsonItem.id
                            : 'ui-' +
                                Math.random()
                                    .toString(36)
                                    .substr(2, 9));
            }
            if (jsonItem.children) {
                assignHiddenNames(jsonItem.children);
            }
        });
    }
}
function parseFormVersion1(json) {
    const parsed = [];
    json.forEach(item => {
        parsed.push(parseFormVersion1Item(item));
    });
    return parsed;
}
function parseFormVersion1Item(item) {
    const schema = {};
    if (item.properties && item.properties.class) {
        if (!schema.attributes) {
            schema.attributes = {};
        }
        schema.attributes.class = item.properties.class;
    }
    if (item.component) {
        Object.assign(schema, {
            component: item.component,
            properties: item.componentInputs ? item.componentInputs : {}
        });
    }
    if (item.controlGroupName) {
        Object.assign(schema, {
            name: item.controlGroupName,
            type: FlexyFormFieldType.Group,
            validators: item.validators,
            groupKey: item.groupKey,
            items: item.items ? parseFormVersion1Item(item.items) : void 0,
            indexDef: item.itemKeyDef,
            indexPattern: item.itemKeyPattern,
            indexGenPattern: item.itemKeyGen
        });
    }
    else if (item.controlArrayName) {
        Object.assign(schema, {
            name: item.controlArrayName,
            type: FlexyFormFieldType.Array,
            validators: item.validators,
            items: item.items ? parseFormVersion1Item(item.items) : void 0,
            indexDef: item.itemIndexDef
        });
    }
    else if (item.controlName) {
        Object.assign(schema, {
            name: item.controlName,
            validators: item.validators
        });
    }
    if (item.children) {
        schema.children = parseFormVersion1(item.children);
    }
    return schema;
}
function replaceMarker(s, marker, key) {
    return s.split(marker).join('' + key);
}

const jsonata$3 = jsonata_;
const ifExpressionsCache = {};
const calculatedExpresionCache = {};
var FlexyFormDataMode;
(function (FlexyFormDataMode) {
    FlexyFormDataMode["All"] = "all";
    FlexyFormDataMode["Dirty"] = "dirty";
    FlexyFormDataMode["Touched"] = "toched";
})(FlexyFormDataMode || (FlexyFormDataMode = {}));
function findErrors(schema, currentData) {
    const errors = {};
    for (const item of schema) {
        if (checkIf(item, currentData) && item.items) {
            item.items.forEach((aItem, index) => {
                const arrItemError = findErrors([aItem], currentData);
                if (arrItemError && Object.values(arrItemError).length) {
                    errors[item.formName + '.' + index] = arrItemError;
                }
            });
        }
        else if (checkIf(item, currentData) &&
            item.formName &&
            item.formControl &&
            item.formControl.invalid) {
            errors[item.formName] = item.formControl.errors;
        }
        if (checkIf(item, currentData) && item.children) {
            Object.assign(errors, findErrors(item.children, currentData));
        }
    }
    return errors;
}
function findSchema(fieldName, schema) {
    for (const item of schema) {
        if (item.formName && item.formName === fieldName) {
            return item;
        }
        else if (item.children) {
            const childSchema = findSchema(fieldName, item.children);
            if (childSchema) {
                return childSchema;
            }
        }
    }
    return null;
}
function calculate(calcExp, data) {
    let value;
    try {
        if (!calculatedExpresionCache[calcExp]) {
            calculatedExpresionCache[calcExp] = jsonata$3(calcExp);
        }
        value = calculatedExpresionCache[calcExp].evaluate(data);
    }
    catch (e) {
        // console.error(e);
        value = null;
    }
    return value;
}
function getSchemaData$1(schemas, currentData, mode = FlexyFormDataMode.All) {
    let data = {};
    if (schemas) {
        schemas.forEach(schema => {
            const fieldSchema = schema;
            if (checkIf(fieldSchema, currentData)) {
                const isFormControl = fieldSchema.formControl && fieldSchema.formName;
                if (isFormControl && fieldSchema.formControl instanceof FormControl) {
                    if (checkSchemaData(fieldSchema.formControl, mode)) {
                        set(data, fieldSchema.formName, fieldSchema.formControl.value);
                    }
                }
                else if (isFormControl && fieldSchema.formControl instanceof FormArray) {
                    const arrayData = getArrayData(fieldSchema, currentData, mode, data);
                    if (mode === FlexyFormDataMode.All) {
                        set(data, fieldSchema.formName, Object.values(arrayData));
                    }
                    else if (!isInputEmpty(arrayData)) {
                        set(data, fieldSchema.formName, arrayData);
                    }
                }
                if (checkIf(fieldSchema, currentData)) {
                    data = merge(data, getSchemaData$1(fieldSchema.children, currentData, mode));
                }
            }
        });
    }
    return data;
}
function findRemoved(allData, originalData) {
    const removed = {};
    if (originalData) {
        Object.keys(originalData).forEach(key => {
            const path = key;
            if (!isInputEmpty(originalData[key]) && isInputEmpty(allData[key])) {
                set(removed, path, null);
            }
            else if (originalData[key] && Array.isArray(originalData[key])) {
                originalData[key].forEach((item, index) => {
                    if (!isInputEmpty(item) && isInputEmpty(allData[key][index])) {
                        if (!has(removed, path)) {
                            set(removed, path, {});
                        }
                        const v = get(removed, path);
                        v['' + index] = null;
                    }
                    else if (item && isObject(item)) {
                        const founded = findRemoved(allData[key][index], item);
                        if (founded && !isInputEmpty(founded)) {
                            if (!has(removed, path)) {
                                set(removed, path, {});
                            }
                            const v = get(removed, path);
                            v['' + index] = founded;
                        }
                    }
                });
            }
            else if (originalData[key] && isObject(originalData[key])) {
                const founded = findRemoved(allData[key], originalData[key]);
                if (founded && !isInputEmpty(founded)) {
                    set(removed, path, founded);
                }
            }
        });
    }
    return removed;
}
function clearEmptyArrayAndObjects(data) {
    if (data) {
        if (isObject(data)) {
            Object.keys(data).forEach(key => {
                if (isEmptyStructure(data[key])) {
                    delete data[key];
                }
                else if (isObject(data[key])) {
                    clearEmptyArrayAndObjects(data[key]);
                }
            });
        }
    }
}
function isObject(a) {
    return !!a && a.constructor === Object;
}
function checkIf(fieldSchema, currentData) {
    if (!fieldSchema.if) {
        return true;
    }
    const ifName = 'IF_' + fieldSchema.if;
    let ret;
    try {
        if (!ifExpressionsCache[ifName]) {
            ifExpressionsCache[ifName] = jsonata$3(fieldSchema.if);
        }
        ret = ifExpressionsCache[ifName].evaluate(currentData ? currentData : {});
    }
    catch (e) {
        // console.error(e);
        ret = null;
    }
    return !!ret;
}
function getArrayData(fieldSchema, currentData, mode, data) {
    const arrayData = {};
    fieldSchema.items.forEach((item, index) => {
        const itemFormControl = item.formControl;
        if (!itemFormControl || checkSchemaData(itemFormControl, mode)) {
            if (item.children) {
                const itemData = getSchemaData$1(item.children, currentData, mode);
                if (!isInputEmpty(itemData)) {
                    arrayData['' + index] = itemData;
                }
            }
            else {
                arrayData['' + index] = item.formControl.value;
            }
        }
    });
    return arrayData;
}
function checkSchemaData(control, mode) {
    return (control &&
        (mode === FlexyFormDataMode.All ||
            (mode === FlexyFormDataMode.Dirty && control.dirty) ||
            (mode === FlexyFormDataMode.Touched && control.touched)));
}
function isInputEmpty(v) {
    return v === void 0 || v === '';
}
function isEmptyStructure(data) {
    let ret = true;
    if (Array.isArray(data)) {
        if (data.length > 0) {
            data.forEach(item => {
                ret = ret && isEmptyStructure(item);
            });
        }
    }
    else if (isObject(data)) {
        if (Object.keys(data).length > 0) {
            Object.keys(data).forEach(key => {
                ret = ret && isEmptyStructure(data[key]);
            });
        }
    }
    else {
        return isInputEmpty(data);
    }
    return ret;
}

class FlexyForm extends FlexyLayout {
    currentData;
    currentDataHash;
    currentData$;
    get valid() {
        return !this.getAllErrors();
    }
    isStarted = false;
    formGroup;
    _originalData;
    _currentDataSubject;
    _calculatedRefs = {};
    _lastErrors;
    _changesSubscription;
    constructor(formGroup, schema, data) {
        super(schema);
        this._currentDataSubject = new BehaviorSubject(data);
        this.currentData$ = this._currentDataSubject.asObservable();
        this.formGroup = formGroup;
        this.schema = schema;
        this._initCalculatedRefs(schema);
        this._originalData = cloneDeep(data);
        this._setCurrentData();
        // refresh attributes
        this._setCurrentData();
        // jump to next tick
        // setTimeout(() => {
        this._subscribeChangesAndCalculate();
        // });
    }
    getAllData() {
        const data = cloneDeep(getSchemaData$1(this.schema, this.currentData));
        this._clearHiddenData(data);
        return data;
    }
    // @deprecated
    getDirtyData() {
        const data = cloneDeep(getSchemaData$1(this.schema, this.currentData, FlexyFormDataMode.Dirty));
        this._clearHiddenData(data);
        clearEmptyArrayAndObjects(data);
        const allData = this.getAllData();
        const removed = findRemoved(allData, this._originalData);
        clearEmptyArrayAndObjects(removed);
        return merge(data, removed);
    }
    getAllErrors() {
        return this._lastErrors;
    }
    containsFieldSchema(fieldName) {
        return !!findSchema(fieldName, this.schema);
    }
    getFieldSchema(fieldName) {
        return findSchema(fieldName, this.schema);
    }
    getFieldInstance(fieldName) {
        const schema = findSchema(fieldName, this.schema);
        if (schema && schema.componentRef) {
            return schema.componentRef.instance;
        }
        return null;
    }
    _subscribeChangesAndCalculate() {
        this._setCurrentData();
        this.isStarted = true;
        // this._setCurrentData();
        this._changesSubscription = this.formGroup.valueChanges.subscribe(data => {
            const hash = this.currentDataHash;
            this._setCurrentData();
            if (hash !== this.currentDataHash) {
                this._currentDataSubject.next(this.currentData);
            }
        });
        this._currentDataSubject.next(this.currentData);
    }
    _setCurrentData() {
        this.currentData = getSchemaData$1(this.schema, this.currentData);
        this.currentDataHash = JSON.stringify(this.currentData);
        this._calculate();
        this.currentData = getSchemaData$1(this.schema, this.currentData);
        this.currentDataHash = JSON.stringify(this.currentData);
        const errors = findErrors(this.schema, this.currentData);
        this._lastErrors = errors && Object.keys(errors).length ? errors : null;
    }
    _initCalculatedRefs(schema) {
        if (schema) {
            schema.forEach((schemaItem) => {
                if (schemaItem.formName && schemaItem.formControl && schemaItem.calc) {
                    this._calculatedRefs[schemaItem.formName] = {
                        calc: schemaItem.calc,
                        control: schemaItem.formControl
                    };
                }
                if (schemaItem.children) {
                    this._initCalculatedRefs(schemaItem.children);
                }
            });
        }
    }
    _calculate() {
        if (this._calculatedRefs) {
            Object.values(this._calculatedRefs).forEach(calc => {
                const value = calculate(calc.calc, this.currentData);
                if (value !== calc.control.value) {
                    calc.control.setValue(value);
                    calc.control.markAsDirty();
                }
            });
        }
    }
    _clearHiddenData(data) {
        if (data[HIDDEN_CALC_GROUP_NAME]) {
            delete data[HIDDEN_CALC_GROUP_NAME];
        }
    }
}

const FLEXY_FORM_VALIDATORS = new InjectionToken('FLEXY_FORM_VALIDATORS');

const INPUTS_READONLY_KEY = 'readonly';
const SCHEMA_CONTROL_NAME_KEY = 'name';
const SCHEMA_GROUP_KEY = 'groupKey';
const SCHEMA_COMPONENT_INPUTS_KEY = 'properties';
const SCHEMA_DEFAULT_KEY = 'default';
const DEFAULT_VALIDATORS_MAP = {
    required: () => Validators.required,
    maxLength: data => Validators.maxLength(data),
    minLength: data => Validators.minLength(data),
    min: data => FlexyFormsValidators.minValidator(data),
    max: data => FlexyFormsValidators.maxValidator(data),
    number: () => FlexyFormsValidators.numberValidator,
    integer: () => FlexyFormsValidators.integerValidator,
    boolean: () => FlexyFormsValidators.booleanValidator,
    email: () => FlexyFormsValidators.emailValidator,
    noWhitespace: () => FlexyFormsValidators.noWhitespaceValidator,
    notEmpty: () => FlexyFormsValidators.notEmptyValidator,
    pattern: data => Validators.pattern(data),
    crossField: data => FlexyFormsValidators.crossFieldValidator(data),
    crossFieldMin: data => FlexyFormsValidators.crossFieldMinValidator(data),
    crossFieldMax: data => FlexyFormsValidators.crossFieldMaxValidator(data),
    crossFieldAbsoluteMin: data => FlexyFormsValidators.crossFieldAbsoluteMinValidator(data),
    forbiddenValues: data => FlexyFormsValidators.forbiddenValuesValidator(data),
    arrayUniqueFields: data => FlexyFormsValidators.arrayUniqueFieldsValidator(data),
    minItems: data => FlexyFormsValidators.minLengthArray(data),
    maxItems: data => FlexyFormsValidators.maxLengthArray(data)
};
class FlexyFormJsonMapperService {
    jsonLayoutMapper;
    formBuilder;
    logger;
    static controlCounter = 0;
    get supportedValidators() {
        return Object.keys(this._validatorsMap);
    }
    _validatorsMap = DEFAULT_VALIDATORS_MAP;
    constructor(validatorsMap, jsonLayoutMapper, formBuilder, logger) {
        this.jsonLayoutMapper = jsonLayoutMapper;
        this.formBuilder = formBuilder;
        this.logger = logger;
        if (validatorsMap) {
            Object.assign(this._validatorsMap, validatorsMap);
        }
    }
    createForm(json, readonlyMode = false, formData) {
        this.logger.debug('createForm');
        FlexyFormJsonMapperService.controlCounter = 0;
        const jsonSchema = parseFormJson(json);
        const rootFormGroup = new FormGroup({});
        const dynamicSchema = this.map(jsonSchema, readonlyMode, formData, rootFormGroup);
        this.logger.debug('countOfControls', FlexyFormJsonMapperService.controlCounter);
        return new FlexyForm(rootFormGroup, dynamicSchema, formData);
    }
    createItemControl(itemsSchema, readonlyMode, value) {
        let control;
        if (itemsSchema.children) {
            control = new FormGroup({});
            this.mapItem(itemsSchema, readonlyMode, value, control);
        }
        else {
            control = this.formBuilder.control(value ? value : get(itemsSchema, 'componentInputs.default'), itemsSchema.validators
                ? this.mapValidators(itemsSchema.validators)
                : []);
        }
        return control;
    }
    createArrayItemSchema(control, items, itemKeyDef, parentName, readonlyMode, formData, value, index, parentSchema = null) {
        const citems = cloneDeep(items);
        this.populateComplexTypeIndexMarker([citems], index + 1, value, itemKeyDef);
        const isComplex = citems && !!citems.children;
        let schema;
        if (isComplex) {
            const withRootValues = { ...value };
            const groupSchema = this._jsonLayoutItemMap({}, '' + index, parentSchema);
            groupSchema.children = this.map([citems], readonlyMode, withRootValues, control, groupSchema);
            schema = groupSchema;
        }
        else {
            schema = this.jsonLayoutMapper.map([citems])[0];
            schema.formControl = control;
            control.setValue(value);
            schema.id = parentSchema.id + ':' + index;
            if (!schema.componentInputs) {
                schema.componentInputs = {};
            }
            schema.componentInputs[INPUTS_READONLY_KEY] = readonlyMode;
        }
        return schema;
    }
    createGroupItemSchema(control, items, itemKeyDef, parentName, readonlyMode, formData, value, key, parentSchema = null) {
        const citems = cloneDeep(items);
        this.populateComplexTypeIndexMarker([citems], key, value, itemKeyDef);
        const isComplex = citems && !!citems.children;
        let schema;
        if (isComplex) {
            const withRootValues = { ...value };
            const groupSchema = this.map([citems], readonlyMode, withRootValues, control, null)[0];
            schema = groupSchema;
        }
        else {
            schema = this.jsonLayoutMapper.map([citems])[0];
            schema.formControl = control;
            control.setValue(value);
            if (!schema.componentInputs) {
                schema.componentInputs = {};
            }
            schema.componentInputs[INPUTS_READONLY_KEY] = readonlyMode;
            schema.formName = citems.name;
        }
        schema.id = (parentSchema && parentSchema.id ? parentSchema.id + ':' : '') + key;
        schema.groupKey = key;
        return schema;
    }
    createSchema(json, readonlyMode = false, formData = {}, parentFormGroup, parentControlGroupName, parentSchema = null) {
        const schema = [];
        if (json && Array.isArray(json)) {
            json.forEach((jsonItem, index) => {
                const schemaItem = this.mapItem(jsonItem, readonlyMode, formData, parentFormGroup, parentControlGroupName, parentSchema, '' + index);
                let itemParentFormGroup = parentFormGroup;
                let itemParentControlGroupName = parentControlGroupName;
                if (schemaItem.formControl instanceof FormGroup) {
                    itemParentFormGroup = schemaItem.formControl;
                    if ([FlexyFormFieldType.Group, FlexyFormFieldType.Array].includes(jsonItem.type)) {
                        itemParentControlGroupName = this.controlComplexName(jsonItem, itemParentControlGroupName);
                    }
                }
                if (jsonItem.children) {
                    schemaItem.children = this.createSchema(jsonItem.children, readonlyMode, formData, itemParentFormGroup, itemParentControlGroupName, schemaItem);
                }
                schema.push(schemaItem);
            });
        }
        return schema;
    }
    map(json, readonlyMode = false, formData, parentFormGroup, parentSchema = null) {
        const dynamicSchema = this.createSchema(json, readonlyMode, formData, parentFormGroup, null, parentSchema);
        return dynamicSchema;
    }
    createControl(config) {
        return config instanceof AbstractControl
            ? config
            : config[1]
                ? this.formBuilder.control(config[0], config[1])
                : this.formBuilder.control(config);
    }
    controlComplexName(jsonItem, parentName) {
        return (parentName && jsonItem.name[0] === '.' ? parentName : '') + jsonItem.name;
    }
    mapItem(jsonItem, readonlyMode = false, formData = {}, parentFormGroup, parentControlGroupName = null, parentSchema = null, schemaId = '') {
        const formSchemaItem = this._jsonLayoutItemMap(jsonItem, schemaId, parentSchema);
        if (readonlyMode) {
            if (!formSchemaItem.componentInputs) {
                formSchemaItem.componentInputs = {};
            }
            formSchemaItem.componentInputs[INPUTS_READONLY_KEY] = readonlyMode;
        }
        let controlName = '';
        if (jsonItem.name &&
            jsonItem.type !== FlexyFormFieldType.Group &&
            jsonItem.type !== FlexyFormFieldType.Array) {
            controlName = jsonItem.name;
            this.mapItemSetFieldControl(formSchemaItem, jsonItem, parentControlGroupName, formData);
        }
        else if (jsonItem.items &&
            jsonItem.type === FlexyFormFieldType.Group) {
            const groupJsonItem = jsonItem;
            controlName = groupJsonItem.name;
            this.mapItemSetGroupControl(formSchemaItem, jsonItem, parentControlGroupName, readonlyMode);
            const formGroupName = (parentControlGroupName && groupJsonItem.name[0] === '.' ? parentControlGroupName : '') + groupJsonItem.name;
            const formGroupData = has(formData, formGroupName) ? get(formData, formGroupName) : void 0;
            if (formGroupData) {
                jsonItem.children = [];
                const isComplex = !!groupJsonItem.items.children;
                Object.keys(formGroupData).forEach(key => {
                    const schemaJson = cloneDeep(groupJsonItem.items);
                    schemaJson.name = '.' + key;
                    if (isComplex) {
                        schemaJson.type = FlexyFormFieldType.Group;
                    }
                    schemaJson[SCHEMA_GROUP_KEY] = key;
                    this.populateComplexTypeIndexMarker([schemaJson], key, formGroupData[key], groupJsonItem.indexDef);
                    groupJsonItem.children.push(schemaJson);
                });
            }
        }
        else if (jsonItem.items &&
            jsonItem.type === FlexyFormFieldType.Array) {
            const arrayJsonItem = jsonItem;
            controlName = arrayJsonItem.name;
            this.mapItemSetArrayControl(formSchemaItem, arrayJsonItem, parentControlGroupName, formData, readonlyMode);
        }
        else {
            controlName =
                jsonItem.type === FlexyFormFieldType.Group
                    ? jsonItem.name
                    : formSchemaItem.id
                        ? 'g-' + formSchemaItem.id
                        : 'd-' + Date.now();
            formSchemaItem.groupKey = jsonItem.groupKey;
            // TODO to think: form control is required also for non FlexyFormFieldLayoutSchema
            formSchemaItem.formControl = new FormGroup({}, this.mapValidators(jsonItem.validators));
        }
        const control = formSchemaItem.formControl;
        if (control) {
            parentFormGroup.addControl(this.unifyName(controlName, parentControlGroupName ? this.unifyName(parentControlGroupName) : ''), control);
        }
        return formSchemaItem;
    }
    _jsonLayoutItemMap(jsonItem, schemaId, parentSchema) {
        const schema = this.jsonLayoutMapper.mapItem(jsonItem, schemaId, parentSchema);
        // const SCHEMA_GROUP_KEY = 'groupKey';
        const SCHEMA_IF = 'if';
        const SCHEMA_CALC = 'calc';
        // TODO tothink is problem with populate form group controls from external domain
        [SCHEMA_GROUP_KEY, SCHEMA_IF, SCHEMA_CALC].forEach(key => {
            if (jsonItem[key]) {
                schema[key] = jsonItem[key];
            }
        });
        return schema;
    }
    mapItemSetArrayControl(formSchemaItem, jsonItem, parentControlGroupName, formData, readonlyMode) {
        let formName = (parentControlGroupName && jsonItem.name[0] === '.' ? parentControlGroupName : '') + jsonItem.name;
        // its possible in array in group
        if (formName.endsWith('.')) {
            formName = formName.slice(0, -1);
        }
        const val = has(formData, formName) ? get(formData, formName) : void 0;
        const formControl = this.createArrayControl(jsonItem, readonlyMode, val);
        formSchemaItem.formControl = formControl;
        formSchemaItem.formName = formName;
        if (jsonItem.items) {
            formSchemaItem.items = this.createArrayItems(jsonItem.items, jsonItem.indexDef, formControl, formName, readonlyMode, val, formData, formSchemaItem);
            formSchemaItem.componentInputs = {
                ...formSchemaItem.componentInputs,
                ...{
                    jsonSchema: jsonItem,
                    readonly: readonlyMode
                }
            };
        }
    }
    mapItemSetGroupControl(formSchemaItem, jsonItem, parentControlGroupName, readonlyMode) {
        const formGroupName = (parentControlGroupName && jsonItem.name[0] === '.' ? parentControlGroupName : '') + jsonItem.name;
        formSchemaItem.formControl = new FormGroup({});
        if (jsonItem.items) {
            formSchemaItem.componentInputs = {
                ...formSchemaItem.componentInputs,
                ...{
                    jsonSchema: jsonItem,
                    parentGroupName: formGroupName,
                    readonly: readonlyMode
                }
            };
        }
    }
    mapItemSetFieldControl(formSchemaItem, jsonItem, parentControlGroupName, formData) {
        FlexyFormJsonMapperService.controlCounter++;
        const formName = (parentControlGroupName && jsonItem.name[0] === '.' ? parentControlGroupName : '') + jsonItem.name;
        const val = has(formData, formName) ? get(formData, formName) : void 0;
        const formControl = this.createControl(this.createControlConfig(jsonItem, val));
        formSchemaItem.formName = formName;
        formSchemaItem.formControl = formControl;
    }
    createArrayItems(items, itemKeyDef, arrayControl, parentName, readonlyMode = false, values, formData, parentSchema = null) {
        const formArray = arrayControl;
        const formSchema = [];
        formArray.controls.forEach((control, index) => {
            let value;
            let key;
            if (values && Array.isArray(values)) {
                value = values[index];
                key = '' + index;
            }
            else if (values && typeof values === 'object') {
                key = Object.keys(values)[index];
                value = values[key];
            }
            const schema = this.createArrayItemSchema(control, items, itemKeyDef, parentName, readonlyMode, formData, value, index, parentSchema);
            schema.formName = key;
            formSchema.push(schema);
        });
        return formSchema;
    }
    populateComplexTypeIndexMarker(items, key, value, marker = COMPLEX_TYPE_INDEX_MARKER) {
        items.forEach(item => {
            if (item.name) {
                item.name = replaceMarker(item.name, marker, key);
            }
            if (item.if) {
                item.if = replaceMarker(item.if, marker, key);
            }
            if (item.calc) {
                item.calc = replaceMarker(item.calc, marker, key);
            }
            if (item.attributes) {
                Object.keys(item.attributes).forEach(attr => {
                    if (typeof item.attributes[attr] === 'string') {
                        item.attributes[attr] = replaceMarker('' + item.attributes[attr], marker, key);
                    }
                    else if (typeof item.attributes[attr] === 'object') {
                        Object.keys(item.attributes[attr]).forEach(attrVal => {
                            const replaced = replaceMarker(attrVal, marker, key);
                            item.attributes[attr][attrVal] = replaceMarker('' + item.attributes[attr][attrVal], marker, key);
                            if (replaced !== attrVal) {
                                item.attributes[attr][replaced] = item.attributes[attr][attrVal];
                                delete item.attributes[attr][attrVal];
                            }
                        });
                    }
                });
            }
            if (item[SCHEMA_COMPONENT_INPUTS_KEY]) {
                const componentInputs = ['title', 'label', 'legend'];
                componentInputs.forEach(propName => {
                    if (item[SCHEMA_COMPONENT_INPUTS_KEY][propName]) {
                        item[SCHEMA_COMPONENT_INPUTS_KEY][propName] = replaceMarker(item[SCHEMA_COMPONENT_INPUTS_KEY][propName], marker, key);
                    }
                });
            }
            if (item.children) {
                this.populateComplexTypeIndexMarker(item.children, key, value, marker);
            }
            if (item.items) {
                this.populateComplexTypeIndexMarker([item.items], key, value, marker);
            }
        });
    }
    createControlConfig(item, defaultValue) {
        if (item.name) {
            return [defaultValue !== void 0 ? defaultValue : item[SCHEMA_DEFAULT_KEY], this.mapValidators(item.validators)];
        }
        return [];
    }
    createArrayControl(item, readonlyMode = false, values = []) {
        const arraySchema = item;
        const validators = [];
        // TODO to thkink
        // if (arraySchema.validators['minItems']) {
        //   validators.push(FlexyFormsValidators.minLengthArray(arraySchema.validators['minItems']));
        // }
        // if (arraySchema.validators['maxItems']) {
        //   validators.push(FlexyFormsValidators.maxLengthArray(arraySchema.validators['maxItems']));
        // }
        const formArray = new FormArray([], this.mapValidators(item.validators));
        if (item.type === FlexyFormFieldType.Array && item.name) {
            if (values && Array.isArray(values)) {
                values.forEach(value => {
                    formArray.push(this.createItemControl(arraySchema.items, readonlyMode, value));
                });
            }
            else if (values) {
                console.warn('Wrong type of data. Values should be array', values);
            }
        }
        return formArray;
    }
    unifyName(controlName, parentControlName = '') {
        if (controlName[0] === '.') {
            controlName = controlName.substring(1);
        }
        let name = controlName ? controlName.split('.').join('/') : 'p_' + Date.now();
        if (parentControlName) {
            name = name.replace(parentControlName + '/', '');
        }
        return name;
    }
    mapValidators(jsonValidator) {
        const validators = [];
        if (jsonValidator) {
            Object.keys(jsonValidator).forEach(key => {
                if (this._validatorsMap[key]) {
                    validators.push(this._validatorsMap[key](jsonValidator[key]));
                }
                else {
                    console.warn(`Validator ${key} is not supported`);
                }
            });
        }
        return validators;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormJsonMapperService, deps: [{ token: FLEXY_FORM_VALIDATORS, optional: true }, { token: i1.FlexyLayoutJsonMapperService }, { token: i2.FormBuilder }, { token: i2$1.FlexyLoggerService }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormJsonMapperService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormJsonMapperService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [FLEXY_FORM_VALIDATORS]
                }] }, { type: i1.FlexyLayoutJsonMapperService }, { type: i2.FormBuilder }, { type: i2$1.FlexyLoggerService }] });

const jsonata$2 = jsonata_;
class FlexyFlexyFormIfDirective {
    templateRef;
    viewContainer;
    flexyFormIf;
    constructor(templateRef, viewContainer) {
        this.templateRef = templateRef;
        this.viewContainer = viewContainer;
    }
    _visibility = true;
    _changesSubscription;
    _ifCompiled;
    _viewRef;
    ngOnInit() {
        if (this.flexyFormIf && this.flexyFormIf.schema.if && this.flexyFormIf.form) {
            this._visibility = this._isEnabled(this.flexyFormIf.form.currentData);
            this._changesSubscription = this.flexyFormIf.form.currentData$.subscribe(data => {
                this._visibility = this._isEnabled(data);
                this._render();
            });
        }
        this._render();
    }
    _render() {
        if (this._visibility) {
            if (!this._viewRef) {
                this.viewContainer.clear();
                if (this.templateRef) {
                    this._viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
                }
            }
        }
        else {
            this.viewContainer.clear();
            this._viewRef = null;
        }
    }
    _isEnabled(data) {
        const schema = this.flexyFormIf.schema;
        let is = false;
        if (schema.if) {
            if (!this._ifCompiled) {
                this._ifCompiled = jsonata$2(schema.if);
            }
            try {
                is = !!this._ifCompiled.evaluate(data);
            }
            catch (e) {
                // do nothing
            }
        }
        return is;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFlexyFormIfDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: FlexyFlexyFormIfDirective, isStandalone: false, selector: "[flexyFormIf]", inputs: { flexyFormIf: "flexyFormIf" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFlexyFormIfDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[flexyFormIf]',
                    standalone: false
                }]
        }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }], propDecorators: { flexyFormIf: [{
                type: Input
            }] } });

class FlexyFormContainerComponent {
    form;
    schema;
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: FlexyFormContainerComponent, isStandalone: false, selector: "flexy-form-container", inputs: { form: "form", schema: "schema" }, ngImport: i0, template: `
    <ng-template #tmplRef let-schema let-form="form">
      <ng-container *ngFor="let schemaItem of schema">
        <ng-container *flexyFormIf="{ schema: schemaItem, form: form }">
          <ng-container
            *ngIf="schemaItem.componentType"
            flexyFormContainer
            [componentSchema]="schemaItem"
            [flexyForm]="form"
          ></ng-container>
          <ng-container *ngIf="!schemaItem.componentType">
            <div flexyFormAttributes [componentSchema]="schemaItem" [flexyForm]="form">
              <ng-container *ngIf="schemaItem.children">
                <ng-container *ngTemplateOutlet="tmplRef; context: { $implicit: schemaItem.children, form: form }"></ng-container>
              </ng-container>
            </div>
          </ng-container>
        </ng-container>
      </ng-container>
    </ng-template>

    <ng-content></ng-content>
    <ng-container *ngTemplateOutlet="tmplRef; context: { $implicit: schema, form: form }"></ng-container>
  `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: FlexyFormAttributesDirective, selector: "[flexyFormAttributes]", inputs: ["flexyForm", "componentSchema"] }, { kind: "directive", type: FlexyFormContainerDirective, selector: "[flexyFormContainer]", inputs: ["flexyForm", "componentSchema"] }, { kind: "directive", type: FlexyFlexyFormIfDirective, selector: "[flexyFormIf]", inputs: ["flexyFormIf"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormContainerComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'flexy-form-container',
                    template: `
    <ng-template #tmplRef let-schema let-form="form">
      <ng-container *ngFor="let schemaItem of schema">
        <ng-container *flexyFormIf="{ schema: schemaItem, form: form }">
          <ng-container
            *ngIf="schemaItem.componentType"
            flexyFormContainer
            [componentSchema]="schemaItem"
            [flexyForm]="form"
          ></ng-container>
          <ng-container *ngIf="!schemaItem.componentType">
            <div flexyFormAttributes [componentSchema]="schemaItem" [flexyForm]="form">
              <ng-container *ngIf="schemaItem.children">
                <ng-container *ngTemplateOutlet="tmplRef; context: { $implicit: schemaItem.children, form: form }"></ng-container>
              </ng-container>
            </div>
          </ng-container>
        </ng-container>
      </ng-container>
    </ng-template>

    <ng-content></ng-content>
    <ng-container *ngTemplateOutlet="tmplRef; context: { $implicit: schema, form: form }"></ng-container>
  `
                    // ,
                    // changeDetection: ChangeDetectionStrategy.OnPush
                    ,
                    standalone: false
                }]
        }], propDecorators: { form: [{
                type: Input
            }], schema: [{
                type: Input
            }] } });

const CHNAGES_DEBOUNCE_TIME = 50;
class FlexyFormComponent {
    jsonMapper;
    cdr;
    json;
    data;
    readonly = false;
    changesDebounceTime = CHNAGES_DEBOUNCE_TIME;
    created = new EventEmitter();
    changed = new EventEmitter();
    form;
    _changesSubscription;
    constructor(jsonMapper, cdr) {
        this.jsonMapper = jsonMapper;
        this.cdr = cdr;
    }
    ngOnInit() {
        this.form = this.jsonMapper.createForm(cloneDeep(this.json), this.readonly, this.data);
        this.created.emit(this.form);
        this._changesSubscription = this.form.currentData$
            .pipe(skip(1), debounceTime(this.changesDebounceTime || CHNAGES_DEBOUNCE_TIME))
            .subscribe(data => {
            this.changed.emit({ valid: this.form.valid, data });
        });
    }
    ngOnDestroy() {
        if (this._changesSubscription) {
            this._changesSubscription.unsubscribe();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormComponent, deps: [{ token: FlexyFormJsonMapperService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: FlexyFormComponent, isStandalone: false, selector: "flexy-form", inputs: { json: "json", data: "data", readonly: "readonly", changesDebounceTime: "changesDebounceTime" }, outputs: { created: "created", changed: "changed" }, ngImport: i0, template: `
    <flexy-form-container *ngIf="form" [form]="form" [schema]="form.schema"></flexy-form-container>
  `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FlexyFormContainerComponent, selector: "flexy-form-container", inputs: ["form", "schema"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'flexy-form',
                    template: `
    <flexy-form-container *ngIf="form" [form]="form" [schema]="form.schema"></flexy-form-container>
  `,
                    standalone: false
                }]
        }], ctorParameters: () => [{ type: FlexyFormJsonMapperService }, { type: i0.ChangeDetectorRef }], propDecorators: { json: [{
                type: Input
            }], data: [{
                type: Input
            }], readonly: [{
                type: Input
            }], changesDebounceTime: [{
                type: Input
            }], created: [{
                type: Output
            }], changed: [{
                type: Output
            }] } });

const jsonata$1 = jsonata_;
class FlexyFormAbstractOptionsComponent {
    optionsService;
    logger;
    form;
    // inputs
    options;
    optionsUrl;
    optionsPath;
    optionsMapper;
    optionsRawId;
    optionsFilter;
    loading;
    changesSubscription;
    filterData = {};
    _optionsCache;
    constructor(optionsService, logger) {
        this.optionsService = optionsService;
        this.logger = logger;
    }
    async initOptions() {
        if (this.optionsUrl) {
            this.loading = true;
            const options = await this.optionsService.loadOptions(this.optionsUrl, this.optionsMapper, this.optionsPath).toPromise();
            this._optionsCache = options;
            this.loading = false;
            if (this.optionsFilter && this.optionsFilter.filter) {
                this._setOptionsFiltering();
            }
            else {
                this.options = options;
            }
        }
        else {
            this.loading = false;
        }
    }
    _setOptionsFiltering() {
        try {
            const jsonataExp = jsonata$1(this.optionsFilter.filter);
            this.logger.debug('jsonata', this.optionsFilter.filter);
            this.changesSubscription = this.form.currentData$.subscribe(data => {
                let isChanged = false;
                this.optionsFilter.observableFields.forEach(path => {
                    const vp = get(data, path);
                    if (get(this.filterData, path) !== vp) {
                        set(this.filterData, path, vp);
                        isChanged = true;
                    }
                });
                if (isChanged) {
                    this.logger.debug('evaluate', {
                        optionsList: this._optionsCache,
                        observableFields: this.filterData
                    });
                    const jsonOptions = jsonataExp.evaluate({
                        optionsList: this._optionsCache,
                        observableFields: this.filterData
                    });
                    const options = jsonOptions ? (Array.isArray(jsonOptions) ? jsonOptions : [jsonOptions]) : [];
                    this.options = options.filter(item => !!item);
                }
            });
        }
        catch (e) {
            this.logger.error('Wrong jsonata expresion', this.optionsFilter.filter, e);
        }
    }
}

const REQUIRED_PATTERN_KEY = 'requiredPattern';
class FlexyFormFirstErrorPipe {
    translateService;
    logger;
    constructor(translateService, logger) {
        this.translateService = translateService;
        this.logger = logger;
    }
    transform(errors) {
        if (errors && Object.keys(errors) && Object.keys(errors).length) {
            const key = Object.keys(errors)[0];
            const error = typeof errors[key] === 'object' ? { ...errors[key] } : '';
            this.logger.debug('translate', key, errors[key]);
            if (key === 'pattern') {
                const patternKey = 'FLEXY_FORM_VALIDATION_PATTERN_' + error[REQUIRED_PATTERN_KEY];
                const pattern = this.translateService.instant(patternKey);
                if (pattern && pattern !== patternKey) {
                    error[REQUIRED_PATTERN_KEY] = pattern;
                }
                this.logger.debug('Validation error message: Check pattern translate', patternKey);
            }
            return this.translateService.instant('FLEXY_FORM_VALIDATION_' +
                key
                    .split('-')
                    .join('_')
                    .toUpperCase(), error);
        }
        return '';
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormFirstErrorPipe, deps: [{ token: i1$2.TranslateService }, { token: i2$1.FlexyLoggerService }], target: i0.ɵɵFactoryTarget.Pipe });
    static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormFirstErrorPipe, isStandalone: false, name: "firstError" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormFirstErrorPipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'firstError',
                    standalone: false
                }]
        }], ctorParameters: () => [{ type: i1$2.TranslateService }, { type: i2$1.FlexyLoggerService }] });

class FlexyOptionsMapperPipe {
    constructor() { }
    transform(value, mapper) {
        if (!value || !Array.isArray(value) || !mapper || !mapper.value || !mapper.text) {
            return [];
        }
        else {
            return value
                .filter(item => !!item && item[mapper.value])
                .map(item => ({
                value: item[mapper.value],
                text: item[mapper.text]
            }));
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyOptionsMapperPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
    static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FlexyOptionsMapperPipe, isStandalone: false, name: "flexyOptions" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyOptionsMapperPipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'flexyOptions',
                    standalone: false
                }]
        }], ctorParameters: () => [] });

class FlexyFormSchemaService {
    jsonMapperService;
    constructor(jsonMapperService) {
        this.jsonMapperService = jsonMapperService;
    }
    addGroupItemToSchema(parentSchemaRef, itemKey, groupSchema, controlGroupName, readonly) {
        let schema = null;
        if (!this.validateGroupKey(itemKey, groupSchema)) {
            const jsonSchema = cloneDeep(groupSchema.items);
            jsonSchema.name = controlGroupName;
            jsonSchema.type = FlexyFormFieldType.Group;
            const newValue = jsonSchema && jsonSchema.children ? {} : null;
            const control = this.jsonMapperService.createItemControl(jsonSchema, readonly, newValue);
            parentSchemaRef.formControl.addControl(itemKey, control);
            parentSchemaRef.formControl.markAsDirty();
            schema = this.jsonMapperService.createGroupItemSchema(control, jsonSchema, groupSchema.indexDef, null, readonly, {}, newValue, itemKey, parentSchemaRef.formControl);
            parentSchemaRef.children.push(schema);
            // fix form control - should be the same but is not
            parentSchemaRef.formControl.setControl(itemKey, schema.formControl);
        }
        return schema;
    }
    validateGroupKey(key, groupSchema) {
        const patternReg = groupSchema.indexPattern ? new RegExp(groupSchema.indexPattern, 'g') : null;
        if (!key) {
            return 'empty';
        }
        else if (patternReg && !patternReg.exec(key)) {
            return 'wrong_format';
        }
        return null;
    }
    removeGroupItemToSchema(layoutSchemaRef, index) {
        if (layoutSchemaRef.children[index]) {
            const schemaItem = layoutSchemaRef.children[index];
            const groupKey = schemaItem.groupKey;
            if (groupKey &&
                layoutSchemaRef.formControl &&
                layoutSchemaRef.formControl instanceof FormGroup &&
                layoutSchemaRef.formControl.contains(groupKey)) {
                layoutSchemaRef.children.splice(index, 1);
                layoutSchemaRef.formControl.removeControl(groupKey);
                layoutSchemaRef.formControl.markAsDirty();
                return groupKey;
            }
        }
        return null;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormSchemaService, deps: [{ token: FlexyFormJsonMapperService }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormSchemaService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormSchemaService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: FlexyFormJsonMapperService }] });

function getSchemaData(schema) {
    const fg = new FormGroup({});
    const ff = new FlexyForm(fg, [schema], {});
    const allData = ff.getAllData();
    if (schema.formName) {
        return get(allData, schema.formName);
    }
    else {
        return allData;
    }
}

const jsonata = jsonata_;
class FlexyFormControlOptionsService {
    httpClient;
    logger;
    constructor(httpClient, logger) {
        this.httpClient = httpClient;
        this.logger = logger;
    }
    loadOptions(optionsUrl, optionsMapper = null, optionsPath) {
        if (optionsUrl) {
            return this.httpClient.get(optionsUrl).pipe(map(data => {
                if (data && optionsPath) {
                    data = get(data, optionsPath);
                }
                const options = [];
                if (data && Array.isArray(data) && optionsMapper) {
                    if (typeof optionsMapper === 'string') {
                        options.push(...this._jsonataMapperOptions(optionsMapper, data));
                    }
                    else {
                        options.push(...this._optionsMapper(optionsMapper, data));
                    }
                }
                else if (!optionsMapper) {
                    this.logger.warn('Options loader: optionsMapper is required');
                }
                return options;
            }));
        }
    }
    _jsonataMapperOptions(optionsMapper, data) {
        const options = [];
        try {
            const compiled = jsonata(optionsMapper);
            const jsonOptions = compiled.evaluate({ optionsData: data });
            if (jsonOptions &&
                Array.isArray(jsonOptions) &&
                jsonOptions.length &&
                jsonOptions[0].hasOwnProperty('text') &&
                jsonOptions[0].hasOwnProperty('value')) {
                options.push(...jsonOptions);
            }
            else {
                this.logger.debug('Jsonata error debug', jsonOptions, optionsMapper, data);
                this.logger.warn('Wrong jsonata mapping');
            }
        }
        catch (e) {
            this.logger.error('Wrong jsonata expresion', optionsMapper, e);
        }
        return options;
    }
    _optionsMapper(optionsMapper, data) {
        const textTemplate = this._mapperTemplate(optionsMapper.text);
        const valueTemplate = this._mapperTemplate(optionsMapper.value);
        const prefixTemplate = this._mapperTemplate(optionsMapper.prefixHtml);
        const options = [];
        if (data && data.length) {
            data.forEach(item => {
                options.push({
                    text: item && textTemplate ? textTemplate(item) : '' + get(item, optionsMapper.text),
                    value: item && valueTemplate ? valueTemplate(item) : get(item, optionsMapper.value),
                    prefixHtml: item && prefixTemplate ? prefixTemplate(item) : get(item, optionsMapper.prefixHtml),
                    _raw: item
                });
            });
        }
        return options;
    }
    _mapperTemplate(mapper) {
        if (!mapper) {
            return;
        }
        // check if template?
        if (mapper.includes('<%')) {
            return template(mapper);
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormControlOptionsService, deps: [{ token: i1$3.HttpClient }, { token: i2$1.FlexyLoggerService }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormControlOptionsService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormControlOptionsService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: i2$1.FlexyLoggerService }] });

function findRawValue(rawIdKey, controlValue, options) {
    if (rawIdKey) {
        if (controlValue && Array.isArray(controlValue)) {
            const ret = [];
            controlValue.forEach(valueItem => {
                const v = valueItem && valueItem[rawIdKey];
                if (v) {
                    const el = options && options.find(item => item && item._raw && item._raw[rawIdKey] === v);
                    if (el && el.value) {
                        ret.push(el.value);
                    }
                }
            });
            return ret;
        }
        else {
            if (controlValue && typeof controlValue === 'object' && controlValue[rawIdKey]) {
                const el = options.find(item => item && item._raw && item._raw[rawIdKey] === controlValue[rawIdKey]);
                return el ? el.value : null;
            }
        }
    }
    else {
        return controlValue;
    }
    return;
}
function prepareControlValue(optionsRawId, data) {
    if (data) {
        const cloned = cloneDeep(data);
        if (optionsRawId) {
            if (Array.isArray(cloned)) {
                cloned.forEach(item => {
                    item.value = item && item._raw;
                });
            }
            else {
                cloned.value = cloned && cloned._raw;
            }
        }
        return Array.isArray(cloned) ? cloned.map(el => el && el.value) : cloned.value;
    }
    else {
        return null;
    }
}

function isRequired(control) {
    if (!control) {
        return null;
    }
    let required = false;
    const formControl = new FormControl();
    if (control.validator) {
        const validationResult = control.validator(formControl);
        required = validationResult !== null && validationResult.required === true;
    }
    return required;
}
function markAsDirtyDeep(control) {
    control.markAsDirty();
    if (control instanceof FormGroup) {
        Object.keys(control.controls).forEach(key => markAsDirtyDeep(control.controls[key]));
    }
    else if (control instanceof FormArray) {
        control.controls.forEach(child => markAsDirtyDeep(child));
    }
}

const PUBLIC_COMPONENTS = [
    FlexyFormFirstErrorPipe,
    FlexyOptionsMapperPipe,
    FlexyFormContainerComponent,
    FlexyFormAttributesDirective,
    FlexyFormContainerDirective,
    FlexyFlexyFormIfDirective,
    FlexyFormComponent
];
class FlexyFormsModule {
    static forRoot(validators) {
        return {
            ngModule: FlexyFormsModule,
            providers: [
                {
                    provide: FLEXY_FORM_VALIDATORS,
                    useValue: validators,
                },
            ],
        };
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormsModule, declarations: [FlexyFormFirstErrorPipe,
            FlexyOptionsMapperPipe,
            FlexyFormContainerComponent,
            FlexyFormAttributesDirective,
            FlexyFormContainerDirective,
            FlexyFlexyFormIfDirective,
            FlexyFormComponent], imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, FlexyLayoutModule], exports: [FlexyFormFirstErrorPipe,
            FlexyOptionsMapperPipe,
            FlexyFormContainerComponent,
            FlexyFormAttributesDirective,
            FlexyFormContainerDirective,
            FlexyFlexyFormIfDirective,
            FlexyFormComponent] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormsModule, imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, FlexyLayoutModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FlexyFormsModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, FlexyLayoutModule],
                    declarations: [...PUBLIC_COMPONENTS],
                    exports: [...PUBLIC_COMPONENTS],
                }]
        }] });

/*
 * Public API Surface of form
 */

/**
 * Generated bundle index. Do not edit.
 */

export { COMPLEX_TYPE_INDEX_MARKER, FLEXY_FORM_VALIDATORS, FlexyFlexyFormIfDirective, FlexyForm, FlexyFormAbstractOptionsComponent, FlexyFormAttributesDirective, FlexyFormComponent, FlexyFormContainerComponent, FlexyFormContainerDirective, FlexyFormControlOptionsService, FlexyFormDataMode, FlexyFormFieldType, FlexyFormFirstErrorPipe, FlexyFormJsonMapperService, FlexyFormSchemaService, FlexyFormsModule, FlexyFormsValidators, FlexyOptionsMapperPipe, HIDDEN_CALC_GROUP_NAME, HIDDEN_IF_GROUP_NAME, assignHiddenNames, calculate, checkSchema, clearEmptyArrayAndObjects, findErrors, findRawValue, findRemoved, findSchema, getSchemaData$1 as getSchemaData, isRequired, markAsDirtyDeep, parseFormJson, parseFormVersion1, parseFormVersion1Item, prepareControlValue, replaceMarker };
//# sourceMappingURL=ng-flexy-form.mjs.map