|                                                                                                                         |  | 'use strict';
/*eslint-disable max-len*/
var YAMLException = require('./exception');var Type          = require('./type');
function compileList(schema, name) {  var result = [];
  schema[name].forEach(function (currentType) {    var newIndex = result.length;
    result.forEach(function (previousType, previousIndex) {      if (previousType.tag === currentType.tag &&          previousType.kind === currentType.kind &&          previousType.multi === currentType.multi) {
        newIndex = previousIndex;      }    });
    result[newIndex] = currentType;  });
  return result;}
function compileMap(/* lists... */) {  var result = {        scalar: {},        sequence: {},        mapping: {},        fallback: {},        multi: {          scalar: [],          sequence: [],          mapping: [],          fallback: []        }      }, index, length;
  function collectType(type) {    if (type.multi) {      result.multi[type.kind].push(type);      result.multi['fallback'].push(type);    } else {      result[type.kind][type.tag] = result['fallback'][type.tag] = type;    }  }
  for (index = 0, length = arguments.length; index < length; index += 1) {    arguments[index].forEach(collectType);  }  return result;}
function Schema(definition) {  return this.extend(definition);}
Schema.prototype.extend = function extend(definition) {  var implicit = [];  var explicit = [];
  if (definition instanceof Type) {    // Schema.extend(type)
    explicit.push(definition);
  } else if (Array.isArray(definition)) {    // Schema.extend([ type1, type2, ... ])
    explicit = explicit.concat(definition);
  } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {    // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })
    if (definition.implicit) implicit = implicit.concat(definition.implicit);    if (definition.explicit) explicit = explicit.concat(definition.explicit);
  } else {    throw new YAMLException('Schema.extend argument should be a Type, [ Type ], ' +      'or a schema definition ({ implicit: [...], explicit: [...] })');  }
  implicit.forEach(function (type) {    if (!(type instanceof Type)) {      throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');    }
    if (type.loadKind && type.loadKind !== 'scalar') {      throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');    }
    if (type.multi) {      throw new YAMLException('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');    }  });
  explicit.forEach(function (type) {    if (!(type instanceof Type)) {      throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');    }  });
  var result = Object.create(Schema.prototype);
  result.implicit = (this.implicit || []).concat(implicit);  result.explicit = (this.explicit || []).concat(explicit);
  result.compiledImplicit = compileList(result, 'implicit');  result.compiledExplicit = compileList(result, 'explicit');  result.compiledTypeMap  = compileMap(result.compiledImplicit, result.compiledExplicit);
  return result;};
module.exports = Schema;
 |