text: define(["exports", "../../../@polymer/polymer/polymer-element.js", "../../../@polymer/iron-flex-layout/iron-flex-layout-classes.js", "../../simple-icon/simple-icon.js", "../../simple-icon/lib/simple-icons.js", "../../simple-icon/lib/simple-icon-button.js", "../../../@polymer/iron-pages/iron-pages.js", "../../../@polymer/app-layout/app-toolbar/app-toolbar.js", "../../../@polymer/paper-menu-button/paper-menu-button.js", "../../../@polymer/app-localize-behavior/app-localize-behavior.js", "../../../@polymer/polymer/lib/legacy/class.js", "./eco-json-schema-object.js", "./eco-json-schema-array.js", "./eco-json-schema-boolean.js", "./eco-json-schema-enum.js", "./eco-json-schema-file.js", "./eco-json-schema-input.js"], function (_exports, _polymerElement, _ironFlexLayoutClasses, _simpleIcon, _simpleIcons, _simpleIconButton, _ironPages, _appToolbar, _paperMenuButton, _appLocalizeBehavior, _class, _ecoJsonSchemaObject, _ecoJsonSchemaArray, _ecoJsonSchemaBoolean, _ecoJsonSchemaEnum, _ecoJsonSchemaFile, _ecoJsonSchemaInput) {
    "use strict";
  
    Object.defineProperty(_exports, "__esModule", {
      value: true
    });
    _exports.EcoJsonSchemaWizard = void 0;
  
    var _templateObject_af450010af6311ebbe560fe9c4727db1;
  
    function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = babelHelpers.getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = babelHelpers.getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return babelHelpers.possibleConstructorReturn(this, result); }; }
  
    function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
  
    /**
    `eco-json-schema-wizard` takes in a JSON schema of type object and builds a form,
    exposing a `value` property that represents an object described by the schema.
    
    Given the element:
    
    ```
    <eco-json-schema-wizard schema="[[schema]]" value="{{value}}"></eco-json-schema-wizard>
    ```
    
    And a JSON schema:
    
    ```
    > this.schema = {
      "$schema": "http://json-schema.org/schema#",
      "title": "Contact",
      "type": "object",
      "properties": {
        "name": {
          "title": "Name",
          "type": "string"
        }
      }
    }
    ```
    
    A form will be generated, with the elements `value` looking something like this:
    
    ```
    > this.value
    {
      "name": "Eric"
    }
    ```
    
    Deep / nested schemas are supported for type array and object:
    
    ```
    > this.schema = {
      "$schema": "http://json-schema.org/schema#",
      "title": "Contact",
      "type": "object",
        "phoneNumbers": {
          "title": "Phone numbers",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "type": {
                "title": "Type",
                "type": "string"
              },
              "phoneNumber": {
                "title": "Phone Number",
                "type": "string"
              }
            }
          }
        }
      }
    }
    ```
    
    Validation is handled for strings and number/integers by mapping JSON schema
    validation keywords to `paper-input` attributes; form elements will automatically
    try and validate themselves as users provide input:
    
    ```
    > this.schema = {
      "$schema": "http://json-schema.org/schema#",
      "title": "Contact",
      "type": "object",
      "properties": {
        "name": {
          "title": "Name",
          "type": "string",
          "minLength": 2
        },
        "age": {
          "type": "integer",
          "minimum": 0,
          "exclusiveMinimum": true
        },
        "postalCode": {
          "title": "Postal/Zip Code",
          "type": "string",
          "pattern": "[a-zA-Z][0-9][a-zA-Z]\\s*[0-9][a-zA-Z][0-9]|[0-9]{5}(-[0-9]{4})?"
        },
        "email": {
          "title": "email",
          "type": "string",
          "format": "email"
        }
      }
    }
    ```
    
    Customizing components for schema properties is supported by extending your JSON
    schema. For any schema sub-property (`properties` for `"type": "object"` and
    `items` for `"type": "array"`) a `component` property may be specified, with
    the following options:
    
    - `component.name` - specifies the name of the custom component to use
    - `component.valueProperty` - specifies which property of the custom element
      represents its value
    - `component.properties` - properties that will be set on the element
    
    Example schema using custom components (note that `"valueProperty": "value"` is
    redundant in this case, `"valueProperty": "value"` will be the default if not specified):
    
    ```
    > this.schema = {
      "$schema": "http://json-schema.org/schema#",
      "title": "Contact",
      "type": "object",
      "properties": {
        "phoneNumber": {
          "title": "Phone Number",
          "type": "string",
          "component": {
            "name": "gold-phone-input",
            "valueProperty": "value",
            "properties": {
              "countryCode": "1"
            }
          }
        }
      }
    }
    ```
    
    Items set in `component.properties` will override any attributes / properties set
    by `eco-json-schema-form` elements, making it possible to override JSON schema
    validation properties mapped to `paper-input` attributes:
    
    ```
    > this.schema = {
      "$schema": "http://json-schema.org/schema#",
      "title": "Contact",
      "type": "object",
      "properties": {
        "postalCode": {
          "title": "Postal/Zip Code",
          "type": "string",
          "pattern": "[a-zA-Z][0-9][a-zA-Z]\\s*[0-9][a-zA-Z][0-9]|[0-9]{5}(-[0-9]{4})?",
          "component": {
            "properties": {
              "autoValidate": false
            }
          }
        }
      }
    }
    ```
    
    Putting it all together, this schema:
    
    ```
    > this.schema = {
      "$schema": "http://json-schema.org/schema#",
      "title": "Contact",
      "type": "object",
      "properties": {
        "name": {
          "title": "Name",
          "type": "string",
          "minLength": 2
        },
        "age": {
          "type": "integer",
          "minimum": 0,
          "exclusiveMinimum": true
        },
        "postalCode": {
          "title": "Postal/Zip Code",
          "type": "string",
          "pattern": "[a-zA-Z][0-9][a-zA-Z]\\s*[0-9][a-zA-Z][0-9]|[0-9]{5}(-[0-9]{4})?",
          "component": {
            "properties": {
              "autoValidate": false
            }
          }
        },
        "phoneNumbers": {
          "title": "Phone numbers",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "type": {
                "title": "Type",
                "type": "string"
              },
              "phoneNumber": {
                "title": "Phone Number",
                "type": "string",
                "component": {
                  "name": "gold-phone-input",
                  "valueProperty": "value",
                  "properties": {
                    "countryCode": "1"
                  }
                }
              }
            }
          }
        },
        "emailAddresses": {
          "title": "Emails",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "type": {
                "title": "Type",
                "type": "string"
              },
              "email": {
                "title": "email",
                "type": "string",
                "format": "email"
              }
            }
          }
        }
      }
    }
    ```
    
    Will build a form describing an object:
    
    ```
    > this.value
    {
      "name": "Eric",
      "age": 28,
      "postalCode": "H1W 2C5",
      "phoneNumbers": [
        {
          "type": "Mobile",
          "phoneNumber": "123-456-7890"
        }
      ]
      "emailAddresses": [
        {
          "type": "Personal",
          "email": "eric@wat.com"
        }
      ]
    }
    ```
    
    External validation is supported via the `error` property. By providing an
    object tree with each leaf representing an error message for properties, the
    message will be attached to the appropriate element.
    
    Example, for the Contact schema:
    
    ```
    el.error = {
      "name": "String is too short (0 chars) minimum 2",
      "phoneNumbers": [
        {
          "phoneNumber": "String does not match required format"
        }
      ]
    }
    ```
    
    @group eco Elements
    @element eco-json-schema-wizard
    * @demo demo/index.html
    */
    var EcoJsonSchemaWizard = /*#__PURE__*/function (_mixinBehaviors) {
      babelHelpers.inherits(EcoJsonSchemaWizard, _mixinBehaviors);
  
      var _super = _createSuper(EcoJsonSchemaWizard);
  
      function EcoJsonSchemaWizard() {
        babelHelpers.classCallCheck(this, EcoJsonSchemaWizard);
        return _super.apply(this, arguments);
      }
  
      babelHelpers.createClass(EcoJsonSchemaWizard, [{
        key: "disconnectedCallback",
        value: function disconnectedCallback() {
          this._clearForm();
  
          babelHelpers.get(babelHelpers.getPrototypeOf(EcoJsonSchemaWizard.prototype), "disconnectedCallback", this).call(this);
        }
      }, {
        key: "_buildSchemaProperties",
        value: function _buildSchemaProperties() {
          var ctx = this;
          this._schemaProperties = Object.keys(this.schema.properties || []).map(function (key) {
            var schema = ctx.schema.properties[key];
            var property = {
              property: key,
              label: schema.title || key,
              schema: schema,
              component: schema.component || {}
            };
  
            if (!property.component.valueProperty) {
              property.component.valueProperty = "value";
            }
  
            if (ctx._isSchemaEnum(schema)) {
              property.component.name = property.component.name || "eco-json-schema-enum";
              property.value = "";
            } else if (ctx._isSchemaBoolean(schema.type)) {
              property.component.name = property.component.name || "eco-json-schema-boolean";
              property.value = false;
            } else if (ctx._isSchemaFile(schema.type)) {
              property.component.name = property.component.name || "eco-json-schema-file";
              property.value = "";
            } else if (ctx._isSchemaValue(schema.type)) {
              property.component.name = property.component.name || "eco-json-schema-input";
              property.value = "";
            } else if (ctx._isSchemaObject(schema.type)) {
              property.component.name = property.component.name || "eco-json-schema-object";
              property.component.wizard = true;
              property.value = {};
            } else if (ctx._isSchemaArray(schema.type)) {
              property.component.name = property.component.name || "eco-json-schema-array";
              property.value = [];
            } else {
              return console.error("Unknown property type %s", schema.type);
            }
  
            ctx.push("pages", key);
            ctx.push("titles", schema.title);
            return property;
          });
        }
      }, {
        key: "_schemaPropertyChanged",
        value: function _schemaPropertyChanged(event, detail) {
          if (detail.path && /\.length$/.test(detail.path)) {
            return;
          }
  
          var ctx = this;
          var property = event.target.schemaProperty;
          var path = ["value", property.property];
  
          if (detail.path && /\.splices$/.test(detail.path)) {
            var parts = detail.path.split(".").slice(1, -1);
  
            while (parts.length) {
              path.push(parts.shift());
  
              if (property.keyMap && property.keyMap[path.join(".")]) {
                path = property.keyMap[path.join(".")].split(".");
              }
            }
  
            if (detail.value.keySplices) {
              if (property.keyMap) {
                detail.value.keySplices.forEach(function (splice) {
                  splice.removed.forEach(function (k) {
                    delete property.keyMap[path.concat([k]).join(".")];
                  });
                });
              }
            }
  
            detail.value.indexSplices.forEach(function (splice) {
              var args = [path.join("."), splice.index, splice.removed.length];
  
              if (splice.addedCount) {
                for (var i = 0, ii = splice.addedCount; i < ii; i++) {
                  if (splice.addedKeys && splice.addedKeys[i]) {
                    property.keyMap = property.keyMap || {};
                    property.keyMap[path.concat([splice.addedKeys[i]]).join(".")] = path.concat([i + splice.index]).join(".");
                  }
  
                  args.push(ctx._deepClone(splice.object[i + splice.index]));
                }
              }
  
              ctx.splice.apply(ctx, args);
            });
          } else if (detail.path) {
            var parts = detail.path.split(".").slice(1);
            var v = this.value;
  
            if (!v.hasOwnProperty(property.property)) {
              this.set("value." + property.property, {});
            }
  
            while (parts.length) {
              var k = parts.shift();
              path.push(k);
  
              if (property.keyMap && property.keyMap[path.join(".")]) {
                path = property.keyMap[path.join(".")].split(".");
              }
            }
  
            this.set(path.join("."), this._deepClone(detail.value));
            console.log("value: " + JSON.stringify(this.value));
          }
        }
      }, {
        key: "_setValue",
        value: function _setValue() {
          var ctx = this;
          var value = {};
  
          this._schemaProperties.forEach(function (property) {
            value[property.property] = ctx._deepClone(property.value);
          });
  
          this.value = value;
        }
      }, {
        key: "_buildForm",
        value: function _buildForm() {
          var _this = this;
  
          var ctx = this;
  
          this._schemaProperties.forEach(function (property) {
            var el = ctx.create(property.component.name, {
              label: property.label,
              schema: property.schema,
              schemaProperty: property,
              language: _this.language,
              resources: _this.resources
            });
            el.setAttribute("name", property.property);
            el.className = "flex start-justified";
            property.value = el[property.component.valueProperty];
            ctx.listen(el, property.component.valueProperty.replace(/([A-Z])/g, "-$1").toLowerCase() + "-changed", "_schemaPropertyChanged");
            ctx.shadowRoot.querySelector("#form").appendChild(el);
          });
        }
      }, {
        key: "_removePropertyEl",
        value: function _removePropertyEl(el) {
          if (babelHelpers.typeof(el.schemaProperty) !== (typeof undefined === "undefined" ? "undefined" : babelHelpers.typeof(undefined))) {
            this.unlisten(el, el.schemaProperty.component.valueProperty.replace(/([A-Z])/g, "-$1").toLowerCase() + "-changed", "_schemaPropertyChanged");
          }
  
          el.schemaProperty = null;
          this.shadowRoot.querySelector("#form").removeChild(el);
        }
      }, {
        key: "_clearForm",
        value: function _clearForm() {
          var formEl = this.shadowRoot.querySelector("#form");
  
          while (formEl.firstChild) {
            this._removePropertyEl(formEl.firstChild);
          }
        }
      }, {
        key: "_schemaChanged",
        value: function _schemaChanged() {
          this._clearForm();
  
          this._buildSchemaProperties();
  
          this._buildForm();
  
          this._setValue();
  
          if (this.pages.length > 0) {
            this.set("page", this.pages[0]);
          }
  
          this.set("title", this.titles[0]);
        }
      }, {
        key: "next",
        value: function next() {
          var current = this.pages.indexOf(this.page);
          var next = current;
  
          if (current !== -1) {
            if (current < this.pages.length - 1) {
              next = current + 1;
            }
  
            this.set("page", this.pages[next]);
            this.set("title", this.titles[next]);
          } else {
            console.log("Invalid current page in wizard");
          }
        }
      }, {
        key: "prev",
        value: function prev() {
          var current = this.pages.indexOf(this.page);
          var prev = current;
  
          if (current !== -1) {
            if (current > 0) {
              prev = current - 1;
            }
  
            this.set("page", this.pages[prev]);
            this.set("title", this.titles[prev]);
          } else {
            console.log("Invalid current page in wizard");
          }
        }
      }, {
        key: "submit",
        value: function submit() {
          this.dispatchEvent(new CustomEvent("submit", {
            bubbles: true,
            cancelable: true,
            composed: true,
            detail: true
          }));
        }
      }, {
        key: "_pageChanged",
        value: function _pageChanged() {
          var current = this.pages.indexOf(this.page);
  
          if (current === 0) {
            this.set("hasPrev", false);
          } else {
            this.set("hasPrev", true);
          }
  
          if (current === this.pages.length - 1) {
            this.set("hasNext", false);
          } else {
            this.set("hasNext", true);
          }
        }
      }, {
        key: "_errorChanged",
        value: function _errorChanged() {
          var ctx = this;
          this.shadowRoot.querySelector("#form").childNodes.forEach(function (el) {
            var name = el.getAttribute("name");
  
            if (ctx.error && ctx.error[name]) {
              el.error = ctx.error[name];
            } else {
              el.error = null;
            }
          });
        }
      }, {
        key: "_deepClone",
        value: function _deepClone(o) {
          return JSON.parse(JSON.stringify(o));
        }
      }, {
        key: "_isSchemaValue",
        value: function _isSchemaValue(type) {
          return this._isSchemaBoolean(type) || this._isSchemaNumber(type) || this._isSchemaString(type) || this._isSchemaFile(type);
        }
      }, {
        key: "_isSchemaFile",
        value: function _isSchemaFile(type) {
          if (Array.isArray(type)) {
            return type.indexOf("file") !== -1;
          } else {
            return type === "file";
          }
        }
      }, {
        key: "_isSchemaBoolean",
        value: function _isSchemaBoolean(type) {
          if (Array.isArray(type)) {
            return type.indexOf("boolean") !== -1;
          } else {
            return type === "boolean";
          }
        }
      }, {
        key: "_isSchemaEnum",
        value: function _isSchemaEnum(schema) {
          return !!schema.enum;
        }
      }, {
        key: "_isSchemaNumber",
        value: function _isSchemaNumber(type) {
          if (Array.isArray(type)) {
            return type.indexOf("number") !== -1 || type.indexOf("integer") !== -1;
          } else {
            return type === "number" || type === "integer";
          }
        }
      }, {
        key: "_isSchemaString",
        value: function _isSchemaString(type) {
          if (Array.isArray(type)) {
            return type.indexOf("string") !== -1;
          } else {
            return type === "string";
          }
        }
      }, {
        key: "_isSchemaObject",
        value: function _isSchemaObject(type) {
          return type === "object";
        }
      }, {
        key: "_isSchemaArray",
        value: function _isSchemaArray(type) {
          return type === "array";
        }
      }], [{
        key: "tag",
        get: function get() {
          return "eco-json-schema-wizard";
        }
      }, {
        key: "template",
        get: function get() {
          return (0, _polymerElement.html)(_templateObject_af450010af6311ebbe560fe9c4727db1 || (_templateObject_af450010af6311ebbe560fe9c4727db1 = babelHelpers.taggedTemplateLiteral(["\n      <style is=\"custom-style\" include=\"iron-flex iron-flex-alignment\">\n        :host {\n          display: block;\n          @apply --layout-vertical;\n        }\n\n        paper-input {\n          padding: 2px;\n          --paper-input-container-label: {\n            white-space: normal;\n            position: static;\n            font-size: 22px;\n            color: #fff;\n          }\n        }\n\n        .box,\n        #form {\n          display: -webkit-box;\n          display: -webkit-flex;\n          display: -moz-box;\n          display: -ms-flexbox;\n          display: flex;\n          -webkit-flex-align: center;\n          -ms-flex-align: center;\n          -webkit-align-items: center;\n          align-items: center;\n        }\n\n        .fullbleed {\n          z-index: 1;\n        }\n\n        app-toolbar.bottom {\n          --app-toolbar-color: var(--app-primary-color);\n          --app-toolbar-background: var(--dark-theme-text-color);\n        }\n\n        app-toolbar.bottom simple-icon-button {\n          --app-toolbar-color: var(--dark-theme-text-color);\n          --app-toolbar-background: var(--app-primary-color);\n        }\n      </style>\n      <div class=\"vertical flex layout fullbleed\">\n        <!--\n        simple-icon-button id=\"camButton\" icon=\"editor:insert-photo\" raised>add photo</simple-icon-button\n      -->\n        <app-toolbar>\n          <simple-icon-button\n            id=\"prevButton\"\n            icon=\"arrow-back\"\n            hidden$=\"{{!hasPrev}}\"\n            on-click=\"prev\"\n            raised=\"\"\n            >{{localize('prev')}}</simple-icon-button\n          ><span\n            class=\"title layout horizontal flex\"\n            style=\"white-space: normal\"\n            >[[title]]</span\n          >\n          <simple-icon-button\n            id=\"nextButton\"\n            icon=\"arrow-forward\"\n            hidden$=\"{{!hasNext}}\"\n            on-click=\"next\"\n            raised=\"\"\n            >{{localize('next')}}</simple-icon-button\n          >\n          <simple-icon-button\n            id=\"submitButton\"\n            icon=\"cloud-upload\"\n            on-click=\"submit\"\n            raised=\"\"\n            >{{localize('submit')}}</simple-icon-button\n          >\n        </app-toolbar>\n        <iron-pages\n          id=\"form\"\n          class=\"layout horizontal flex start-justified\"\n          role=\"main\"\n          selected=\"[[page]]\"\n          attr-for-selected=\"name\"\n        ></iron-pages>\n        <app-toolbar class=\"bottom\">\n          <div hidden$=\"{{!hasPrev}}\" on-click=\"prev\">\n            <simple-icon-button id=\"prevButton\" icon=\"arrow-back\" raised=\"\"\n              >{{localize('prev')}}</simple-icon-button\n            >\n            <span class=\"title layout\" style=\"white-space: normal\"\n              >{{localize('prev')}}</span\n            >\n          </div>\n          <span\n            class=\"title layout horizontal flex\"\n            style=\"white-space: normal\"\n          ></span>\n          <div hidden$=\"{{!hasNext}}\" on-click=\"next\">\n            <span class=\"title layout\" style=\"white-space: normal\"\n              >{{localize('next')}}</span\n            >\n            <simple-icon-button id=\"nextButton\" icon=\"arrow-forward\" raised=\"\"\n              >{{localize('next')}}</simple-icon-button\n            >\n          </div>\n        </app-toolbar>\n      </div>\n    "])));
        }
      }, {
        key: "properties",
        get: function get() {
          return {
            language: {
              type: String,
              notify: true
            },
            resources: {
              type: Object,
              notify: true
            },
            schema: {
              type: Object,
              notify: true,
              observer: "_schemaChanged"
            },
            label: {
              type: String
            },
            value: {
              type: Object,
              notify: true,
              value: function value() {
                return {};
              }
            },
            page: {
              type: String,
              notify: true,
              observer: "_pageChanged"
            },
            pages: {
              type: Array,
              notify: true,
              value: []
            },
            error: {
              type: Object,
              observer: "_errorChanged"
            },
            isReview: {
              type: Boolean,
              value: false,
              notify: true
            },
            canSubmit: {
              type: Boolean,
              notify: true
            },
            hasNext: {
              type: Boolean,
              notify: true
            },
            hasPrev: {
              type: Boolean,
              notify: true
            },
            titles: {
              type: Array,
              notify: true,
              value: []
            },
            title: {
              type: String,
              value: "",
              notify: true
            }
          };
        }
      }]);
      return EcoJsonSchemaWizard;
    }((0, _class.mixinBehaviors)([_appLocalizeBehavior.AppLocalizeBehavior], _polymerElement.PolymerElement));
  
    _exports.EcoJsonSchemaWizard = EcoJsonSchemaWizard;
    window.customElements.define(EcoJsonSchemaWizard.tag, EcoJsonSchemaWizard);
  });