SchemaType constructor

@param {String} path
@param {Object} [options]
@param {String} [instance]
@api public
482842
function SchemaType (path, options, instance) {
  this.path = path;
  this.instance = instance;
  this.validators = [];
  this.setters = [];
  this.getters = [];
  this.options = options;
  this._index = null;
  this.selected;

  for (var i in options) if (this[i] && 'function' == typeof this[i]) {
    // { unique: true, index: true }
    if ('index' == i && this._index) continue;

    var opts = Array.isArray(options[i])
      ? options[i]
      : [options[i]];

    this[i].apply(this, opts);
  }
}
896881
function typeFromSchemaResponse(schema, parseOptions) {
  var schemaType = avro.parse(schema);

  //check if the schema has been previouisly parsed and added to the registry
  if(typeof parseOptions.registry === 'object' && typeof parseOptions.registry[schemaType.name] !== 'undefined'){
    return parseOptions.registry[schemaType.name];
  }

  return avro.parse(schema, parseOptions);
}
28245
function simpleType_jsonSchema(name) {
  var result = {};
  result.type = this.instance.toLowerCase();

  __processOptions(result, this.options)

  return result;
}
242144
function _buildMap(schema, options) {
    options = options || {};
    return function(data) {
        return _map(data, schema, options);
    };
}
449597
function Schema(model) {
        var _this = this;
        /**
         * List of generated schemas.
         */
        this.schemas = {};
        this.model = model;
        var models = model.database().models();
        Object.keys(models).forEach(function (name) { _this.one(models[name]); });
    }
988702
function list(schema, defaults, options) {
  if (kindOf(schema) !== 'array' || schema.length !== 1) {
    if (process.env.NODE_ENV !== 'production') {
      throw new Error(
        `List structs must be defined as an array with a single element, but you passed: ${schema}`
      )
    } else {
      throw new Error(`Invalid schema: ${schema}`)
    }
  }

  const array = scalar('array', undefined, options)
  const element = any(schema[0], undefined, options)
  const name = 'list'
  const type = `[${element.type}]`
  const validate = (value = resolveDefaults(defaults)) => {
    const [error, result] = array.validate(value)

    if (error) {
      error.type = type
      return [error]
    }

    value = result
    const errors = []
    const ret = []

    for (let i = 0; i < value.length; i++) {
      const v = value[i]
      const [e, r] = element.validate(v)

      if (e) {
        const allE = e.errors || [e]
        allE.forEach(singleE => {
          singleE.path = [i].concat(singleE.path)
          singleE.data = value
          errors.push(singleE)
        })
        continue
      }

      ret[i] = r
    }

    if (errors.length) {
      const first = errors[0]
      first.errors = errors
      return [first]
    }

    return [undefined, ret]
  }

  return new Kind(name, type, validate)
}
383692
function (schema) {
		if (!schema.key || schema.key === 'base' || !Array.isArray(schema.fields)) {
			return null;
			// throw exception?
		}
		// store it for later reference
		Schemas[schema.key] = schema;
		// add this schema to the NPC object so we can use it as a constructor
		// this could overwrite is that ok?
		const Base = NPC[schema.key] = function () {
			// in case we add something to NPC constructor that we need to call?
			// NPC.Base.call(this);
		};
		Base.prototype = new NPC.Base();
		Base.prototype.constructor = Base;
		Base.prototype.schema = schema.key;
		Base.prototype.fields = [];
		Base.prototype.helpers = {};
		
		// initialize schema properties...
		schema.fields.forEach((f) => {
			let default_ = null;
			switch (f.type) {
				case 'string':
				case 'text':
					default_ = '';
					break;
				case 'array':
					default_ = [];
					break;
				case 'number':
				case 'modifier':
					default_ = 0;
					break;
				case undefined:
					// ?
					break;
			}
			Base.prototype.fields[f.key] = default_;
		});
		
		if (!schema.helpers || typeof schema.helpers !== 'object') { return; }
		const helpers = Object.keys(schema.helpers);
		helpers.forEach((h) => {
			// if (typeof schema.helpers[h] === 'function') {
			//	Base.prototype.helpers[h] = schema.helpers[h];
			// }
			// create a function from the array
			Base.prototype.helpers[h] = new Function(...schema.helpers[h]);
		});
	}
1126620
function get_path(context, path, options = {}) {
	const node = get_node_by_path(context, path, options);
	return node_type(node) == NodeTypes.NODE
		? get_all_node_props(context, node, options)
		: node;
}
1330839
function en(schema, defaults, options) {
  if (kindOf(schema) !== 'array') {
    if (process.env.NODE_ENV !== 'production') {
      throw new Error(
        `Enum structs must be defined as an array, but you passed: ${schema}`
      )
    } else {
      throw new Error(`Invalid schema: ${schema}`)
    }
  }

  const name = 'enum'
  const type = schema
    .map(s => {
      try {
        return JSON.stringify(s)
      } catch (e) {
        return String(s)
      }
    })
    .join(' | ')

  const validate = (value = resolveDefaults(defaults)) => {
    return schema.includes(value)
      ? [undefined, value]
      : [{ data: value, path: [], value, type }]
  }

  return new Kind(name, type, validate)
}
1361745
function SchemaObjectInstanceFactory(schema, options) {
        // Represents an actual instance of an object.
        class SchemaObjectInstance {
            // Extend instance factory.
            static extend(extendSchema, extendOptions = {}) {
                // Extend requires reflection.
                if (_isProxySupported === false) {
                    throw new Error('[schema-object] Extending object requires --harmony flag.');
                }

                // Merge schema and options together.
                const mergedSchema = _.merge({}, schema, extendSchema);
                const mergedOptions = _.merge({}, options, extendOptions);

                // Allow method and constructor to call `this.super()`.
                const methodHomes = ['methods', 'constructors'];
                for (const methodHome of methodHomes) {
                    // Ensure object containing methods exists on both provided and original options.
                    if (_.size(options[methodHome]) && _.size(extendOptions[methodHome])) {
                        // Loop through each method in the original options.
                        // It's not necessary to bind `this.super()` for options that didn't already exist.
                        _.each(options[methodHome], (method, name) => {
                            // The original option may exist, but was it extended?
                            if (extendOptions[methodHome][name]) {
                                // Extend method by creating a binding that takes the `this` context given and adds `self`.
                                // `self` is a reference to the original method, also bound to the correct `this`.
                                mergedOptions[methodHome][name] = function () {
                                    this[_privateKey]._reservedFields.super = () => {
                                        return method.apply(this, arguments);
                                    };
                                    const ret = extendOptions[methodHome][name].apply(this, arguments);
                                    delete this[_privateKey]._reservedFields.super;
                                    return ret;
                                };
                            }
                        });
                    }
                }

                return new SchemaObject(mergedSchema, mergedOptions);
            }

            // Construct new instance pre-populated with values.
            constructor(values, _root) {
                // Object used to store internals.
                const _private = this[_privateKey] = {};

                //
                _private._root = options.inheritRootThis ? _root || this : this;

                // Object with getters and setters bound.
                _private._getset = this;

                // Public version of ourselves.
                // Overwritten with proxy if available.
                _private._this = this;

                // Object used to store raw values.
                const obj = _private._obj = {};

                // Schema as defined by constructor.
                _private._schema = schema;

                // Errors, retrieved with getErrors().
                _private._errors = [];

                // Options need to be accessible. Shared across ALL INSTANCES.
                _private._options = options;

                // Reserved keys for storing internal properties accessible from outside.
                _private._reservedFields = {};

                // Normalize schema properties to allow for shorthand declarations.
                _.each(schema, (properties, index) => {
                    schema[index] = normalizeProperties.call(this, properties, index);
                });

                // Define getters/typecasts based off of schema.
                _.each(schema, (properties, index) => {
                    // Use getter / typecast to intercept and re-route, transform, etc.
                    defineGetter.call(_private._getset, index, properties);
                    defineSetter.call(_private._getset, index, properties);
                });

                // Proxy used as interface to object allows to intercept all access.
                // Without Proxy we must register individual getter/typecasts to put any logic in place.
                // With Proxy, we still use the individual getter/typecasts, but also catch values that aren't in the schema.
                if (_isProxySupported === true) {
                    const proxy = this[_privateKey]._this = new Proxy(this, {
                        // Ensure only public keys are shown.
                        ownKeys: (target) => {
                            return Object.keys(this.toObject());
                        },

                        // Return keys to iterate.
                        enumerate: (target) => {
                            return Object.keys(this[_privateKey]._this)[Symbol.iterator]();
                        },

                        // Check to see if key exists.
                        has: (target, key) => {
                            return !!_private._getset[key];
                        },

                        // Ensure correct prototype is returned.
                        getPrototypeOf: () => {
                            return _private._getset;
                        },

                        // Ensure readOnly fields are not writeable.
                        getOwnPropertyDescriptor: (target, key) => {
                            return {
                                value: proxy[key],
                                writeable: !schema[key] || schema[key].readOnly !== true,
                                enumerable: true,
                                configurable: true
                            };
                        },

                        // Intercept all get calls.
                        get: (target, name, receiver) => {
                            // First check to see if it's a reserved field.
                            if (_reservedFields.includes(name)) {
                                return this[_privateKey]._reservedFields[name];
                            }

                            // Support dot notation via lodash.
                            if (options.dotNotation && typeof name === 'string' && name.indexOf('.') !== -1) {
                                return _.get(this[_privateKey]._this, name);
                            }

                            // Use registered getter without hitting the proxy to avoid creating an infinite loop.
                            return this[name];
                        },

                        // Intercept all set calls.
                        set: (target, name, value, receiver) => {
                            // Support dot notation via lodash.
                            if (options.dotNotation && typeof name === 'string' && name.indexOf('.') !== -1) {
                                return _.set(this[_privateKey]._this, name, value);
                            }

                            // Find real keyname if case sensitivity is off.
                            if (options.keysIgnoreCase && !schema[name]) {
                                name = getIndex.call(this, name);
                            }

                            if (!schema[name]) {
                                if (options.strict) {
                                    // Strict mode means we don't want to deal with anything not in the schema.
                                    // TODO: SetterError here.
                                    return true;
                                } else {
                                    // Add index to schema dynamically when value is set.
                                    // This is necessary for toObject to see the field.
                                    addToSchema.call(this, name, {
                                        type: 'any'
                                    });
                                }
                            }

                            // This hits the registered setter but bypasses the proxy to avoid an infinite loop.
                            this[name] = value;

                            // Necessary for Node v6.0. Prevents error: 'set' on proxy: trap returned falsish for property 'string'".
                            return true;
                        },

                        // Intercept all delete calls.
                        deleteProperty: (target, property) => {
                            this[property] = undefined;
                            return true;
                        }
                    });
                }

                // Populate schema defaults into object.
                _.each(schema, (properties, index) => {
                    if (properties.default !== undefined) {
                        // Temporarily ensure readOnly is turned off to prevent the set from failing.
                        const readOnly = properties.readOnly;
                        properties.readOnly = false;
                        this[index] = _.isFunction(properties.default) ? properties.default.call(this) : properties.default;
                        properties.readOnly = readOnly;
                    }
                });

                // Call default constructor.
                _private._options.constructors.default.call(this, values);

                // May return actual object instance or Proxy, depending on harmony support.
                return _private._this;
            }

            // Populate values.
            populate(values) {
                for (const key in values) {
                    this[_privateKey]._this[key] = values[key];
                }
            }

            // Clone and return SchemaObject.
            clone() {
                return new SchemaObjectInstance(this.toObject(), this[_privateKey]._root);
            }

            // Return object without getter/typecasts, extra properties, etc.
            toObject() {
                const options = this[_privateKey]._options;
                let getObj = {};

                // Populate all properties in schema.
                _.each(this[_privateKey]._schema, (properties, index) => {
                    // Do not write values to object that are marked as invisible.
                    if (properties.invisible) {
                        return;
                    }

                    // Fetch value through the public interface.
                    let value = this[_privateKey]._this[index];

                    // Do not write undefined values to the object because of strange behavior when using with MongoDB.
                    // MongoDB will convert undefined to null and overwrite existing values in that field.
                    if (value === undefined && options.setUndefined !== true) {
                        return;
                    }

                    // Clone objects so they can't be modified by reference.
                    if (_.isObject(value)) {
                        if (value._isSchemaObject) {
                            value = value.toObject();
                        } else if (value._isSchemaArray) {
                            value = value.toArray();
                        } else if (_.isArray(value)) {
                            value = value.splice(0);
                        } else if (_.isDate(value)) {
                            // https://github.com/documentcloud/underscore/pull/863
                            // _.clone doesn't work on Date object.
                            getObj[index] = new Date(value.getTime());
                        } else {
                            value = _.clone(value);
                        }

                        // Don't write empty objects or arrays.
                        if (!_.isDate(value) && !options.setUndefined && !_.size(value)) {
                            return;
                        }
                    }

                    // Write to object.
                    getObj[index] = value;
                });

                // If options contains toObject, pass through before returning final object.
                if (_.isFunction(options.toObject)) {
                    getObj = options.toObject.call(this, getObj);
                }

                return getObj;
            }

            // toJSON is an interface used by JSON.stringify.
            // Return the raw object if called.
            toJSON() {
                return this.toObject();
            }

            // Clear all values.
            clear() {
                _.each(this[_privateKey]._schema, (properties, index) => {
                    clearField.call(this[_privateKey]._this, index, properties);
                });
            }

            // Get all errors.
            getErrors() {
                const errors = [];
                for (let error of this[_privateKey]._errors) {
                    error = _.cloneDeep(error);
                    error.schemaObject = this;
                    errors.push(error);
                }

                _.each(this[_privateKey]._schema, (properties, index) => {
                    let required = properties.required;
                    let message = `${index} is required but not provided`;

                    //If required is an array, set custom message
                    if (Array.isArray(required)) {
                      message = required[1] || message;
                      required = required[0];
                    }
                    //Skip if required does not exist
                    if (!required) {
                        return;
                    }
                    //Skip if required is a function, but returns false
                    else if (typeof required === 'function' && !required.call(this)) {
                        return;
                    }

                    //Skip if property has a value, is a boolean set to false, or if it's falsy and falsy values are allowed
                    if (
                      this[index] ||
                      typeof this[index] === 'boolean' ||
                      this[_privateKey]._options.allowFalsyValues && this[index] !== undefined
                    ) {
                      return;
                    }

                    const error = new SetterError(message, this[index], this[index], properties);
                    error.schemaObject = this;
                    errors.push(error);
                });

                // Look for sub-SchemaObjects.
                for (const name in this[_privateKey]._schema) {
                    const field = this[_privateKey]._schema[name];
                    if (field.type === 'object' && typeof field.objectType === 'function') {
                        const subErrors = this[name].getErrors();
                        for (const subError of subErrors) {
                            subError.fieldSchema.name = `${name}.${subError.fieldSchema.name}`;
                            subError.schemaObject = this;
                            errors.push(subError);
                        }
                    }
                }

                return errors;
            }

            // Clear all errors
            clearErrors() {
                this[_privateKey]._errors.length = 0;

                // Look for sub-SchemaObjects.
                for (const name in this[_privateKey]._schema) {
                    const field = this[_privateKey]._schema[name];
                    if (field.type === 'object' && typeof field.objectType === 'function') {
                        this[name].clearErrors();
                    }
                }
            }

            // Has errors?
            isErrors() {
                return this.getErrors().length > 0;
            }

            // Used to detect instance of schema object internally.
            _isSchemaObject() {
                return true;
            }
        }

        // Add custom methods to factory-generated class.
        _.each(options.methods, (method, key) => {
            if (SchemaObjectInstance.prototype[key]) {
                throw new Error(`Cannot overwrite existing ${key} method with custom method.`);
            }
            SchemaObjectInstance.prototype[key] = method;
        });

        return SchemaObjectInstance;
    }
1008197
function instanceRender (schema, opts) {
  if (_.isString(schema)) {
    schema = JSON.parse(schema)
  }

  if (!_.isPlainObject(schema)) {
    throw new Error('Must be plain object')
  }

  // find entry points
  var rootPath = walkBFS.call(this, schema, (v, k, p) => {
    if (k === '__schema') {
      return p
    }
  })

  if (!rootPath) {
    throw new Error('Cannot find "__schema" object')
  }

  var root = _.get(schema, rootPath)
  var graphRoot = getGraphRoot.call(this, root)
  var q = graphRoot.q
  var types = graphRoot.types

  // walk the graph & build up nodes & edges
  var current
  var entities = {}

  while (q.length) {
    current = q.shift()

    // if item has already been processed
    if (entities[current]) {
      continue
    }

    // process item
    q = q.concat(processType.call(this, current, entities, types))
  }

  // process all the enum fields
  var enums = this.theme.enums.hide
    ? []
    : _.chain(types)
        .filter(type => {
          return type.kind === 'ENUM' && !_.startsWith(type.name, '__')
        })
        .map(processEnumType.bind(this))
        .value()

  // process all the input fields
  var inputs = this.theme.inputs.hide
    ? []
    : _.chain(types)
        .filter(type => {
          return type.kind === 'INPUT_OBJECT' && !_.startsWith(type.name, '__')
        })
        .map(processInputType.bind(this))
        .value()

  var interfaces = _.filter(entities, {
    isInterfaceType: true
  })

  var unions = _.filter(entities, {
    isUnionType: true
  })

  var objects = _.filter(entities, {
    isInterfaceType: false,
    isUnionType: false
  })

  // build the dot
  var dotfile =
    'digraph erd {\n' +
    'graph [\n' +
    '  rankdir = "LR"\n' +
    '];\n' +
    'node [\n' +
    '  fontsize = "16"\n' +
    '  shape = "plaintext"\n' +
    '];\n' +
    'edge [\n' +
    '];\n'

  dotfile += graph.call(this, objects, this.theme.types)
  dotfile += graph.call(this, enums, this.theme.enums)
  dotfile += graph.call(this, interfaces, this.theme.interfaces)
  dotfile += graph.call(this, inputs, this.theme.inputs)
  dotfile += graph.call(this, unions, this.theme.unions)

  dotfile += '\n\n'

  // key by to prevent need to search by name
  var processedTypes = _.keyBy(
    _.union(objects, enums, interfaces, inputs, unions),
    'name'
  )

  dotfile += _.reduce(
    processedTypes,
    (result, processedType) => {
      if (!processedType.isEnumType) {
        _.each(processedType.fields, field => {
          var fieldType = processedTypes[field.type]
          if (
            fieldType &&
            isEnabled.call(this, fieldType) &&
            (this.theme.edgesToSelf || processedType.name !== fieldType.name)
          ) {
            result.push(
              createEdge.call(this, {
                from: {
                  typeName: getTypeDisplayName(processedType.name),
                  fieldName: field.name
                },
                to: {
                  typeName: getTypeDisplayName(fieldType.name)
                },
                color: getColor.call(this, field)
              })
            )
          }
          if (!this.theme.field.noargs && field.args && field.args.length) {
            _.each(field.args, arg => {
              var argType = processedTypes[arg.type]
              if (
                argType &&
                isEnabled.call(this, argType) &&
                (this.theme.edgesToSelf || argType.name !== processedType.name)
              ) {
                result.push(
                  createEdge.call(this, {
                    from: {
                      typeName: getTypeDisplayName(argType.name)
                    },
                    to: {
                      typeName: getTypeDisplayName(processedType.name),
                      fieldName: this.theme.anchor.input ? field.name : null
                    },
                    label: this.theme.edgeLabels.input,
                    color: this.theme.inputs.hide
                      ? getColor.call(this, argType)
                      : this.theme.inputs.color,
                    weight: 1000
                  })
                )
              }
            })
          }
        })
        _.each(processedType.possibleTypes, possibleTypeName => {
          var possibleType = _.find(entities, { name: possibleTypeName })
          if (
            possibleType &&
            isEnabled.call(this, possibleType) &&
            (this.theme.edgesToSelf || processedType.name !== possibleType.name)
          ) {
            result.push(
              createEdge.call(this, {
                from: {
                  typeName: getTypeDisplayName(processedType.name)
                },
                to: {
                  typeName: getTypeDisplayName(possibleType.name)
                },
                label: processedType.isUnionType
                  ? this.theme.edgeLabels.union
                  : this.theme.edgeLabels.interface,
                color: getColor.call(this, possibleType)
              })
            )
          }
        })
      }
      return result
    },
    []
  ).join('\n')

  dotfile += '\n\n'

  dotfile += '\n}'

  return dotfile
}
77379
function compileSchema(type) {
      var schema = {}, globalAttributes, blockContent;
      var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent;

      function add(name, attributes, children) {
        var ni, attributesOrder, element;

        function arrayToMap(array, obj) {
          var map = {}, i, l;

          for (i = 0, l = array.length; i < l; i++) {
            map[array[i]] = obj || {};
          }

          return map;
        }

        children = children || [];
        attributes = attributes || "";

        if (typeof children === "string") {
          children = split(children);
        }

        name = split(name);
        ni = name.length;
        while (ni--) {
          attributesOrder = split([globalAttributes, attributes].join(' '));

          element = {
            attributes: arrayToMap(attributesOrder),
            attributesOrder: attributesOrder,
            children: arrayToMap(children, dummyObj)
          };

          schema[name[ni]] = element;
        }
      }

      function addAttrs(name, attributes) {
        var ni, schemaItem, i, l;

        name = split(name);
        ni = name.length;
        attributes = split(attributes);
        while (ni--) {
          schemaItem = schema[name[ni]];
          for (i = 0, l = attributes.length; i < l; i++) {
            schemaItem.attributes[attributes[i]] = {};
            schemaItem.attributesOrder.push(attributes[i]);
          }
        }
      }

      // Use cached schema
      if (mapCache[type]) {
        return mapCache[type];
      }

      // Attributes present on all elements
      globalAttributes = "id accesskey class dir lang style tabindex title role";

      // Event attributes can be opt-in/opt-out
      /*eventAttributes = split("onabort onblur oncancel oncanplay oncanplaythrough onchange onclick onclose oncontextmenu oncuechange " +
       "ondblclick ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop ondurationchange onemptied onended " +
       "onerror onfocus oninput oninvalid onkeydown onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart " +
       "onmousedown onmousemove onmouseout onmouseover onmouseup onmousewheel onpause onplay onplaying onprogress onratechange " +
       "onreset onscroll onseeked onseeking onseeking onselect onshow onstalled onsubmit onsuspend ontimeupdate onvolumechange " +
       "onwaiting"
       );*/

      // Block content elements
      blockContent =
        "address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul";

      // Phrasing content elements from the HTML5 spec (inline)
      phrasingContent =
        "a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd " +
        "label map noscript object q s samp script select small span strong sub sup " +
        "textarea u var #text #comment"
        ;

      // Add HTML5 items to globalAttributes, blockContent, phrasingContent
      if (type != "html4") {
        globalAttributes += " contenteditable contextmenu draggable dropzone " +
          "hidden spellcheck translate";
        blockContent += " article aside details dialog figure header footer hgroup section nav";
        phrasingContent += " audio canvas command datalist mark meter output picture " +
          "progress time wbr video ruby bdi keygen";
      }

      // Add HTML4 elements unless it's html5-strict
      if (type != "html5-strict") {
        globalAttributes += " xml:lang";

        html4PhrasingContent = "acronym applet basefont big font strike tt";
        phrasingContent = [phrasingContent, html4PhrasingContent].join(' ');

        each(split(html4PhrasingContent), function (name) {
          add(name, "", phrasingContent);
        });

        html4BlockContent = "center dir isindex noframes";
        blockContent = [blockContent, html4BlockContent].join(' ');

        // Flow content elements from the HTML5 spec (block+inline)
        flowContent = [blockContent, phrasingContent].join(' ');

        each(split(html4BlockContent), function (name) {
          add(name, "", flowContent);
        });
      }

      // Flow content elements from the HTML5 spec (block+inline)
      flowContent = flowContent || [blockContent, phrasingContent].join(" ");

      // HTML4 base schema TODO: Move HTML5 specific attributes to HTML5 specific if statement
      // Schema items <element name>, <specific attributes>, <children ..>
      add("html", "manifest", "head body");
      add("head", "", "base command link meta noscript script style title");
      add("title hr noscript br");
      add("base", "href target");
      add("link", "href rel media hreflang type sizes hreflang");
      add("meta", "name http-equiv content charset");
      add("style", "media type scoped");
      add("script", "src async defer type charset");
      add("body", "onafterprint onbeforeprint onbeforeunload onblur onerror onfocus " +
        "onhashchange onload onmessage onoffline ononline onpagehide onpageshow " +
        "onpopstate onresize onscroll onstorage onunload", flowContent);
      add("address dt dd div caption", "", flowContent);
      add("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn", "", phrasingContent);
      add("blockquote", "cite", flowContent);
      add("ol", "reversed start type", "li");
      add("ul", "", "li");
      add("li", "value", flowContent);
      add("dl", "", "dt dd");
      add("a", "href target rel media hreflang type", phrasingContent);
      add("q", "cite", phrasingContent);
      add("ins del", "cite datetime", flowContent);
      add("img", "src sizes srcset alt usemap ismap width height");
      add("iframe", "src name width height", flowContent);
      add("embed", "src type width height");
      add("object", "data type typemustmatch name usemap form width height", [flowContent, "param"].join(' '));
      add("param", "name value");
      add("map", "name", [flowContent, "area"].join(' '));
      add("area", "alt coords shape href target rel media hreflang type");
      add("table", "border", "caption colgroup thead tfoot tbody tr" + (type == "html4" ? " col" : ""));
      add("colgroup", "span", "col");
      add("col", "span");
      add("tbody thead tfoot", "", "tr");
      add("tr", "", "td th");
      add("td", "colspan rowspan headers", flowContent);
      add("th", "colspan rowspan headers scope abbr", flowContent);
      add("form", "accept-charset action autocomplete enctype method name novalidate target", flowContent);
      add("fieldset", "disabled form name", [flowContent, "legend"].join(' '));
      add("label", "form for", phrasingContent);
      add("input", "accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate " +
        "formtarget height list max maxlength min multiple name pattern readonly required size src step type value width"
      );
      add("button", "disabled form formaction formenctype formmethod formnovalidate formtarget name type value",
        type == "html4" ? flowContent : phrasingContent);
      add("select", "disabled form multiple name required size", "option optgroup");
      add("optgroup", "disabled label", "option");
      add("option", "disabled label selected value");
      add("textarea", "cols dirname disabled form maxlength name readonly required rows wrap");
      add("menu", "type label", [flowContent, "li"].join(' '));
      add("noscript", "", flowContent);

      // Extend with HTML5 elements
      if (type != "html4") {
        add("wbr");
        add("ruby", "", [phrasingContent, "rt rp"].join(' '));
        add("figcaption", "", flowContent);
        add("mark rt rp summary bdi", "", phrasingContent);
        add("canvas", "width height", flowContent);
        add("video", "src crossorigin poster preload autoplay mediagroup loop " +
          "muted controls width height buffered", [flowContent, "track source"].join(' '));
        add("audio", "src crossorigin preload autoplay mediagroup loop muted controls " +
          "buffered volume", [flowContent, "track source"].join(' '));
        add("picture", "", "img source");
        add("source", "src srcset type media sizes");
        add("track", "kind src srclang label default");
        add("datalist", "", [phrasingContent, "option"].join(' '));
        add("article section nav aside header footer", "", flowContent);
        add("hgroup", "", "h1 h2 h3 h4 h5 h6");
        add("figure", "", [flowContent, "figcaption"].join(' '));
        add("time", "datetime", phrasingContent);
        add("dialog", "open", flowContent);
        add("command", "type label icon disabled checked radiogroup command");
        add("output", "for form name", phrasingContent);
        add("progress", "value max", phrasingContent);
        add("meter", "value min max low high optimum", phrasingContent);
        add("details", "open", [flowContent, "summary"].join(' '));
        add("keygen", "autofocus challenge disabled form keytype name");
      }

      // Extend with HTML4 attributes unless it's html5-strict
      if (type != "html5-strict") {
        addAttrs("script", "language xml:space");
        addAttrs("style", "xml:space");
        addAttrs("object", "declare classid code codebase codetype archive standby align border hspace vspace");
        addAttrs("embed", "align name hspace vspace");
        addAttrs("param", "valuetype type");
        addAttrs("a", "charset name rev shape coords");
        addAttrs("br", "clear");
        addAttrs("applet", "codebase archive code object alt name width height align hspace vspace");
        addAttrs("img", "name longdesc align border hspace vspace");
        addAttrs("iframe", "longdesc frameborder marginwidth marginheight scrolling align");
        addAttrs("font basefont", "size color face");
        addAttrs("input", "usemap align");
        addAttrs("select", "onchange");
        addAttrs("textarea");
        addAttrs("h1 h2 h3 h4 h5 h6 div p legend caption", "align");
        addAttrs("ul", "type compact");
        addAttrs("li", "type");
        addAttrs("ol dl menu dir", "compact");
        addAttrs("pre", "width xml:space");
        addAttrs("hr", "align noshade size width");
        addAttrs("isindex", "prompt");
        addAttrs("table", "summary width frame rules cellspacing cellpadding align bgcolor");
        addAttrs("col", "width align char charoff valign");
        addAttrs("colgroup", "width align char charoff valign");
        addAttrs("thead", "align char charoff valign");
        addAttrs("tr", "align char charoff valign bgcolor");
        addAttrs("th", "axis align char charoff valign nowrap bgcolor width height");
        addAttrs("form", "accept");
        addAttrs("td", "abbr axis scope align char charoff valign nowrap bgcolor width height");
        addAttrs("tfoot", "align char charoff valign");
        addAttrs("tbody", "align char charoff valign");
        addAttrs("area", "nohref");
        addAttrs("body", "background bgcolor text link vlink alink");
      }

      // Extend with HTML5 attributes unless it's html4
      if (type != "html4") {
        addAttrs("input button select textarea", "autofocus");
        addAttrs("input textarea", "placeholder");
        addAttrs("a", "download");
        addAttrs("link script img", "crossorigin");
        addAttrs("iframe", "sandbox seamless allowfullscreen"); // Excluded: srcdoc
      }

      // Special: iframe, ruby, video, audio, label

      // Delete children of the same name from it's parent
      // For example: form can't have a child of the name form
      each(split('a form meter progress dfn'), function (name) {
        if (schema[name]) {
          delete schema[name].children[name];
        }
      });

      // Delete header, footer, sectioning and heading content descendants
      /*each('dt th address', function(name) {
       delete schema[name].children[name];
       });*/

      // Caption can't have tables
      delete schema.caption.children.table;

      // Delete scripts by default due to possible XSS
      delete schema.script;

      // TODO: LI:s can only have value if parent is OL

      // TODO: Handle transparent elements
      // a ins del canvas map

      mapCache[type] = schema;

      return schema;
    }
976098
function Schema(config, data) {
    const controllers = data.controllers;
    const length = controllers.length;

    this.FullyTyped = FullyTyped;

    // apply controllers to this schema
    for (let i = 0; i < length; i++) controllers[i].call(this, config);

    // add additional properties
    if (config._extension_ && typeof config._extension_ === 'object') {
        const self = this;
        Object.keys(config._extension_).forEach(function(key) {
            self[key] = config._extension_[key];
        });
    }

    // store protected data with schema
    const protect = Object.assign({}, data);

    // create and store hash
    const options = getNormalizedSchemaConfiguration(this);
    protect.hash = crypto
        .createHash('sha256')
        .update(JSON.stringify(prepareForHash(options)))
        .digest('hex');
    instances.set(this, protect);

    /**
     * @name Schema#config
     * @type {object}
     */
    Object.defineProperty(this, 'config', {
        get: function() {
            return util.copy(config);
        }
    });
}
844378
function schemaType(schema) {
    let type;
    if (schema.hasOwnProperty('type')) {
        type = schema.type;
    } else if (schema.hasOwnProperty('properties') || schema.hasOwnProperty('allOf') || schema.hasOwnProperty('additionalProperties')) {
        type = 'object';
    } else if (schema.hasOwnProperty('items')) {
        type = 'array';
    }

    switch (type) {
        case 'array':
        case 'boolean':
        case 'file':
        case 'integer':
        case 'number':
        case 'object':
        case 'string':
            return type;
    }
}
1028340
function initJsonSchema (args) {
    // get global validator instance
    var validator = this.global().validator
    // get schema id based on model name - must be globally unique
    this.schemaId = '/model/'+this.name
    // set option to perform schema validation on created/update
    this.validateSchema = args.validate === false ? false : true
    // create schema for model
    var schema = this.schemaMeta = {
        id: this.schemaId,
        properties: {},
        required: [],
        type: 'object',
    }
    // get data column
    var dataColumn = this.columnName('data')
    // create entry in schema for data if model has data
    if (dataColumn) {
        // schema id for data only
        this.schemaDataId = '/model/'+this.name+'/data'
        // create data schema - meta and data schemas are compiled without
        // ref so that the complete schemas can be easily sent to clients
        var schemaData = this.schemaData = schema.properties[dataColumn] = {
            additionalProperties: args.additionalProperties,
            id: this.schemaDataId,
            properties: {},
            type: 'object',
        }
        // merge schema from args over data schema
        _.merge(schemaData.properties, args.properties)
        // if required properties are set then add
        if (args.required) {
            // required must be array
            if (typeof args.required === 'string') {
                args.required = [args.required]
            }
            // throw error if not array
            assert.ok(Array.isArray(args.required), 'required must be array or string')
            // add list of required properties
            schemaData.required = args.required
        }
        // add data schema
        validator.addSchema(schemaData, this.schemaDataId)
    }
    // create schema for each default column
    _.each(this.defaultColumns, (defaultName, columnName) => {
        // skip data column which is already specified
        if (defaultName === 'data') {
            return
        }
        // get column spec
        var column = this.columns[columnName]
        // if there is not schema for type then skip
        if (!defaultSchemas[column.type]) {
            return
        }
        // get column schema
        var columnSchema = _.cloneDeep(defaultSchemas[column.type])
        // set default schema based on type
        schema.properties[columnName] = columnSchema
        // make property required unless nullable
        if (column.null === false) {
            schema.required.push(columnName)
        }
    })
    // add schema
    validator.addSchema(schema, this.schemaId)
}
759966
private boolean isMap(PropertyPath path) {
        if (schemaRoot != null) {
            Schema schema = this.schemaRoot.find(path);
            return schema != null && (schema.hasChild(NodeId.ANY_KEY) || schema.hasChild(NodeId.ANY));
        }
        return false;
    }
666729
function getSchema(path) {
        var parts = path.split('.');
        var collectionName = parts[0];
        var fieldName = parts[1];

        // if format not user.field or field not in the schemaDefinitions object, then log error without breaking
        if (parts.length !== 2 || !schemaDefinitions[collectionName] || !schemaDefinitions[collectionName][fieldName]) {
            log.error('No schemaDefinitions for : ' + path, null);
            return {};
        }

        return schemaDefinitions[collectionName][fieldName];
    }